Scheduled maintenance is currently in progress. We will provide updates as necessary.
Posted Jul 28, 2026 - 16:40 UTC
Scheduled
As part of our continuous improvement and security enhancement efforts, we are rolling out a security fix for our Object Storage S3 offering.
This update addresses an authorization validation issue related to AWS Signature Version 4 (SigV4).
Previously, requests could include additional x-amz-* headers that were not included in the signature validation process. In some cases, this could allow a presigned URL request to be modified by adding unsigned, meaningful headers (such as x-amz-copy-source), potentially altering the intended operation.
Following this update, our gateway will enforce the same behavior as AWS S3: all x-amz-* headers included in a request must be part of the SignedHeaders list.
Requests containing unsigned x-amz-* headers will now be rejected.
Start time : 27/07/2026 08:00 UTC End time : 28/07/2026 10:00 UTC Service impact : Customers using properly signed SigV4 requests will not experience any impact. Customers relying on unsigned x-amz-* headers in their requests may need to update their request signing process to ensure all x-amz-* headers are included in the signature.
A request with an unsigned `x-amz-*` header now returns **HTTP 403** with : ```xml
AccessDenied
There were headers present in the request which were not signed x-amz-storage-class
``` The HeadersNotSigned element names the offending header, so it is easy to diagnose.
Are you affected?
- **Standard SDKs (boto3, AWS SDKs) and the AWS CLI: not affected.** They already sign every `x-amz-*` header they send. Keep your SDK reasonably up to date and you have nothing to do. - **You may be affected if** you build requests by hand, or generate a presigned URL and then attach extra `x-amz-*` headers (storage class, ACL, tagging, user metadata, copy-source, SDK checksum headers…) at request time. Those headers must be part of the signature. - **One exception:** `x-amz-content-sha256` does not need to be listed in `SignedHeaders` its value already *is* the payload hash bound into the signature. (`x-amz-date` **does** have to be signed.)
How to presign requests correctly
The rule is the same in every language: **put the `x-amz-*` headers into the signing step, and make the caller replay exactly those headers** — never add an `x-amz-*` header to an already-generated presigned URL.
Python (boto3)
**Do sign the headers at generation time** — pass them to `generate_presigned_url` via `Params` so boto3 folds them into the signature:
// Replay req.SignedHeader as-is; do not add or drop any x-amz-* header. httpReq, _ := http.NewRequest(req.Method, req.URL, bytes.NewReader(payload)) httpReq.Header = req.SignedHeader.Clone() // ... send httpReq with your HTTP client ... ```
Direct (non-presigned) calls need no change — the SDK signs every `x-amz-*` header:
// presigned.url() is the URL; the caller MUST send presigned.signedHeaders() // (x-amz-storage-class, x-amz-acl, x-amz-meta-team, ...) unchanged. } ```
Direct (non-presigned) calls need no change — the SDK signs every `x-amz-*` header:
Use `generate_presigned_post` (or the equivalent in your SDK) — the fields are covered by the signed policy document, so this pattern is already correct.
Action required
Review any code that (a) hand-crafts SigV4 requests, or (b) adds `x-amz-*` headers to a presigned URL after it was generated. Move those headers into the signing step as shown above. If you rely on standard SDKs, no action is needed.