Is your feature request related to a problem? Please describe.
We are using Nextcloud Server with an S3-compatible primary object store on Hetzner Object Storage.
The backend accepts normal object writes, but operations that rely on server-side CopyObject fail with 501 Not Implemented / NotImplemented. A direct diagnostic against the same bucket shows:
PutObject: OK
CopyObject: fails
GetObject + PutObject: OK
This means the instance is not generally misconfigured for S3 access; the failure is specifically tied to CopyObject.
Hetzner documents CopyObject as a notable exception and says that it "depends on internal factors and may fail, even if the Buckets are in the same location."
In practice, this breaks valid user workflows in the Files app on an otherwise working S3-compatible setup.
Describe the solution you'd like
When the S3 backend receives 501 Not Implemented / NotImplemented from CopyObject, fall back to a client-side copy:
GetObject from the source key
PutObject to the destination key
- preserve metadata / content type / encryption headers as far as possible
- if the higher-level operation is a move, delete the source only after the fallback copy succeeds
I would keep this fallback narrow and only trigger it for explicit "operation not implemented" responses, not for generic copy failures.
This would make Nextcloud more robust with partially compatible S3 providers without changing behavior for backends where CopyObject works as documented by the S3 API.
Describe alternatives you've considered
- avoiding providers that do not fully support
CopyObject
- maintaining a local patch/fork
- adding an admin option to disable server-side copy and always use streamed copy on selected S3 backends
- adding provider capability detection, though that seems more complex than a targeted fallback on
501 / NotImplemented
Additional context
Use case in the Files app:
- uploading a file to the primary object store works
- renaming a file in
Files can hit the S3 copy path and fail
- moving a file to another folder in
Files can hit the same path and fail
- copying a file in
Files is also affected for the same reason
From the deployment used here:
- Nextcloud Server version:
32.0.12
- Web server:
Nginx
- Database:
PostgreSQL (local dev stack uses postgres:17.7-alpine)
- Deployment style: containerized (
docker compose)
- Object storage settings include:
OBJECTSTORE_S3_HOST=fsn1.your-objectstorage.com
OBJECTSTORE_S3_PORT=443
OBJECTSTORE_S3_USEPATH_STYLE=true
OBJECTSTORE_S3_SSE_C_KEY
Is your feature request related to a problem? Please describe.
We are using Nextcloud Server with an S3-compatible primary object store on Hetzner Object Storage.
The backend accepts normal object writes, but operations that rely on server-side
CopyObjectfail with501 Not Implemented/NotImplemented. A direct diagnostic against the same bucket shows:PutObject: OKCopyObject: failsGetObject+PutObject: OKThis means the instance is not generally misconfigured for S3 access; the failure is specifically tied to
CopyObject.Hetzner documents
CopyObjectas a notable exception and says that it "depends on internal factors and may fail, even if the Buckets are in the same location."In practice, this breaks valid user workflows in the Files app on an otherwise working S3-compatible setup.
Describe the solution you'd like
When the S3 backend receives
501 Not Implemented/NotImplementedfromCopyObject, fall back to a client-side copy:GetObjectfrom the source keyPutObjectto the destination keyI would keep this fallback narrow and only trigger it for explicit "operation not implemented" responses, not for generic copy failures.
This would make Nextcloud more robust with partially compatible S3 providers without changing behavior for backends where
CopyObjectworks as documented by the S3 API.Describe alternatives you've considered
CopyObject501/NotImplementedAdditional context
Use case in the Files app:
Filescan hit the S3 copy path and failFilescan hit the same path and failFilesis also affected for the same reasonFrom the deployment used here:
32.0.12NginxPostgreSQL(local dev stack usespostgres:17.7-alpine)docker compose)OBJECTSTORE_S3_HOST=fsn1.your-objectstorage.comOBJECTSTORE_S3_PORT=443OBJECTSTORE_S3_USEPATH_STYLE=trueOBJECTSTORE_S3_SSE_C_KEY