Skip to content
Subnomic
← Back to blog
Storage Oct 27, 2026 · 1 min read

The region is part of the signature

AuthorizationHeaderMalformed reads like a bug in your client. It is a setting: the region your requests are signed for.

Point an S3 client at Subnomic Storage without setting a region, and the first request fails:

AuthorizationHeaderMalformed: The authorization header is malformed;
the region 'us-east-1' is wrong; expecting 'eu-west-1'

The fix is one setting. Why it is needed takes a little longer, and it is the same for every S3-compatible service, not just ours.

The region is inside the key

S3 requests are signed with AWS Signature Version 4. The client never sends its secret. It sends a signature made with a key derived from the secret, and the derivation takes the date, the region and the service as inputs, one HMAC after another. The same scope travels in the request in plain text:

Credential=<access key id>/20261029/eu-west-1/s3/aws4_request

So a request signed for us-east-1 was signed with a different key from one signed for eu-west-1. A server that expects one cannot check the other, however right the secret is. Most SDKs default to us-east-1, which is why this is so often the first error anybody sees against S3-compatible storage.

Say what is wrong

A server could answer that request with SignatureDoesNotMatch, and strictly it would be right. It would also send you off to regenerate keys, check clocks and compare canonical requests for an hour.

Subnomic Storage reads the region from the credential scope before it looks the key up, and when the region is not the one it signs with, it answers the way S3 does: AuthorizationHeaderMalformed, naming the region it expected. The same check applies to presigned URLs, which carry their region in X-Amz-Credential.

Setting it

The AWS CLI, per profile or in CI:

aws configure set region eu-west-1 --profile subnomic
# or, in a pipeline
export AWS_REGION=eu-west-1

boto3, on the client:

s3 = boto3.client("s3", endpoint_url="https://objects.subnomic.com", region_name="eu-west-1")

rclone, in the remote:

[subnomic]
type = s3
provider = Other
endpoint = https://objects.subnomic.com
region = eu-west-1

A presigned link is signed when it is made, so set the region on the client that presigns, not on whoever opens the link.

Complete setups, with path-style addressing and access keys, are in S3 clients. Why Storage is the S3 API rather than an SDK of its own is in An object store you can leave.