Summary
In a legacy etcd bucket-federation deployment, a whole-object CopyObject across deployments fails with 400 InvalidArgument whenever the source object is stored inline — which is every small object.
Evidence
Same federation harness as #99, both object-layer backends:
PUT /remoteBucket/dst
x-amz-copy-source: /srcBucket/src (source is a 26-byte object)
->
400
<Error><Code>InvalidArgument</Code>
<Message>Your metadata headers are not supported.</Message>…
probe: source reserved metadata forwarded to remote = [x-minio-internal-inline-data]
With x-amz-metadata-directive: REPLACE the copy succeeds, because the source's stored metadata is then not forwarded. The default COPY directive fails.
Cause
cmd/object-handlers.go, federated branch of CopyObjectHandler, strips exactly two reserved keys before forwarding the source metadata to the remote deployment:
delete(srcInfo.UserDefined, ReservedMetadataPrefix+"compression")
delete(srcInfo.UserDefined, ReservedMetadataPrefix+"actual-size")
opts := miniogo.PutObjectOptions{UserMetadata: srcInfo.UserDefined, …}
x-minio-internal-inline-data survives. The remote deployment's setRequestLimitMiddleware rejects any request carrying a ReservedMetadataPrefix header (containsReservedMetadata, cmd/generic-handlers.go:75), so the forwarded write is refused before it reaches a handler.
Provenance and scope
Inherited upstream breakage, not a regression. Verified: containsReservedMetadata, the federated branch, and ReservedMetadataPrefixLower+"inline-data" (cmd/storage-datatypes.go:379) are all unchanged from RELEASE.2026-08-06T00-00-00Z, so the same failure reproduces there.
Affects only legacy etcd bucket federation. Not release-gating.
Also observed on this path
The object the federated write does persist carries a random UUID as its ETag rather than the content MD5 (e.g. 55c406332dda4c6ab7863da0325c67e3 = 55c40633-2dda-4c6a-b786-3da0325c67e3), because the forwarded write sends no Content-MD5. Same code path, same provenance; recorded here rather than opened separately.
Expected
Filter the reserved metadata prefix as a class before forwarding, instead of removing two known keys, so the federated copy does not depend on which internal keys a source object happens to carry.
Summary
In a legacy etcd bucket-federation deployment, a whole-object
CopyObjectacross deployments fails with 400 InvalidArgument whenever the source object is stored inline — which is every small object.Evidence
Same federation harness as #99, both object-layer backends:
With
x-amz-metadata-directive: REPLACEthe copy succeeds, because the source's stored metadata is then not forwarded. The defaultCOPYdirective fails.Cause
cmd/object-handlers.go, federated branch ofCopyObjectHandler, strips exactly two reserved keys before forwarding the source metadata to the remote deployment:x-minio-internal-inline-datasurvives. The remote deployment'ssetRequestLimitMiddlewarerejects any request carrying aReservedMetadataPrefixheader (containsReservedMetadata,cmd/generic-handlers.go:75), so the forwarded write is refused before it reaches a handler.Provenance and scope
Inherited upstream breakage, not a regression. Verified:
containsReservedMetadata, the federated branch, andReservedMetadataPrefixLower+"inline-data"(cmd/storage-datatypes.go:379) are all unchanged fromRELEASE.2026-08-06T00-00-00Z, so the same failure reproduces there.Affects only legacy etcd bucket federation. Not release-gating.
Also observed on this path
The object the federated write does persist carries a random UUID as its ETag rather than the content MD5 (e.g.
55c406332dda4c6ab7863da0325c67e3=55c40633-2dda-4c6a-b786-3da0325c67e3), because the forwarded write sends noContent-MD5. Same code path, same provenance; recorded here rather than opened separately.Expected
Filter the reserved metadata prefix as a class before forwarding, instead of removing two known keys, so the federated copy does not depend on which internal keys a source object happens to carry.