From: Matthew N. Heler Date: Wed, 6 May 2026 16:10:32 +0000 (-0500) Subject: rgw/cloud-transition: url-encode rgwx-source-key metadata header X-Git-Tag: v21.0.1~2^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=6226e68b744fa33de62fcc1aa19629d541b8df6e;p=ceph.git rgw/cloud-transition: url-encode rgwx-source-key metadata header For non-ASCII object keys, raw UTF-8 bytes end up in the signed x-amz-meta-rgwx-source-key header. Strict S3-compatible backends normalize non-ASCII bytes when verifying SigV4, producing a signature mismatch -> HTTP 403, surfaced in LC as -EACCES (-13). url_encode() the value before signing. The header is write-only, so no decode is needed. Signed-off-by: Matthew N. Heler --- diff --git a/src/rgw/driver/rados/rgw_lc_tier.cc b/src/rgw/driver/rados/rgw_lc_tier.cc index 56e49a63d39..c02d19f2b52 100644 --- a/src/rgw/driver/rados/rgw_lc_tier.cc +++ b/src/rgw/driver/rados/rgw_lc_tier.cc @@ -823,9 +823,10 @@ void RGWLCCloudStreamPut::init_send_attrs(const DoutPrefixProvider *dpp, attrs["x-amz-meta-rgwx-source-mtime"] = buf; attrs["x-amz-meta-rgwx-source-etag"] = obj_properties.etag; - attrs["x-amz-meta-rgwx-source-key"] = rest_obj.key.name; + // url-encoded; decode the fields for restore if required + attrs["x-amz-meta-rgwx-source-key"] = url_encode(rest_obj.key.name); if (!rest_obj.key.instance.empty()) { - attrs["x-amz-meta-rgwx-source-version-id"] = rest_obj.key.instance; + attrs["x-amz-meta-rgwx-source-version-id"] = url_encode(rest_obj.key.instance); } for (const auto& a : attrs) { ldpp_dout(dpp, 30) << "init_send_attrs attr[" << a.first << "] = " << a.second <