S3 Error: An error occurred (SignatureDoesNotMatch) when calling the PutObject operation
S3 Error: An error occurred (SignatureDoesNotMatch) when calling the PutObject operation
Fix the hidden signing, region, header, encoding, and request-integrity issues that cause PutObject SignatureDoesNotMatch errors in modern AWS environments
#AWS #S3 #SignatureDoesNotMatch
Problem
You are attempting to upload an object to Amazon S3, and the request fails with the following error:
An error occurred (SignatureDoesNotMatch) when calling the PutObject operation: The request signature we calculated does not match the signature you provided
This error commonly appears during:
- SDK uploads
aws s3 cpaws s3api put-object- pre-signed URL uploads
- browser-based uploads
- Lambda workflows
- CI/CD artifact uploads
- custom HTTP clients
- proxy-routed requests
At first glance, this looks like a credential problem.
Sometimes it is.
But in many real-world cases, the credentials are valid and the request is failing because the request S3 receives is not the same request that was signed.
Clarifying the Issue
This error means AWS recalculated the request signature on its side and got a different result than the signature sent by the client.
That usually means something about the signed request does not match what S3 received.
Common causes include:
- wrong AWS secret access key
- wrong AWS region
- incorrect endpoint
- system clock skew
- modified headers
- URL encoding differences
- pre-signed URL expiration
- proxy or gateway rewriting the request
- SDK/client bug or custom signing mistake
This is not the same as AccessDenied.
With AccessDenied, AWS understands the request but refuses the action.
With SignatureDoesNotMatch, AWS cannot trust the signed request because the signature validation failed.
In many cases, S3 also returns the:
- Canonical Request
- String-to-Sign
inside the XML error response.
Reviewing those values can help identify exactly which header, path, method, or encoding detail differs from the original signed request.
Why It Matters
A SignatureDoesNotMatch failure can block:
- file uploads
- artifact publishing
- browser-to-S3 uploads
- backup workflows
- Lambda-generated upload URLs
- CI/CD deployment pipelines
- customer-facing media uploads
This error is especially painful because it often appears after a system has already authenticated successfully in other AWS workflows.
That can make engineers chase IAM policies when the real issue is request signing.
Key Terms
Signature Version 4 / SigV4 AWS request-signing process used to authenticate API requests
Canonical Request Normalized version of the HTTP request used to calculate the signature
String-to-Sign Intermediate signing value used during SigV4 calculation
Secret Access Key Private key material used to generate the request signature
AWS Region Region included in the signing scope
Pre-Signed URL Time-limited URL containing signing information for a specific request
Signed Headers HTTP headers included in the signature calculation
Steps at a Glance
- Verify the active AWS identity and credentials
- Confirm the bucket region and endpoint
- Check system clock accuracy
- Inspect pre-signed URL generation if used
- Look for header or URL changes after signing
- Test with the AWS CLI or official SDK
Detailed Steps
Step 1. Verify the Active AWS Identity and Credentials
Start by confirming which credentials are actually being used.
Run:
aws sts get-caller-identity
This confirms:
- account ID
- IAM user or role
- assumed role session
Then verify that the environment is not using stale or unexpected credentials.
Common sources of credential confusion include:
- wrong AWS CLI profile
- old environment variables
- expired temporary credentials
- CI/CD secret rotation
- container task-role mismatch
- local credential files overriding expected values
If the secret access key does not match the access key ID being used, the signature will fail.
Step 2. Confirm the Bucket Region and Endpoint
S3 signing depends on the region used in the request.
If the bucket is in:
us-west-2
but the request is signed for:
us-east-1
signature validation may fail.
Check the bucket location:
aws s3api get-bucket-location --bucket my-bucket
Then retry with the correct region:
aws s3 cp file.txt s3://my-bucket/ --region us-west-2
Also confirm the endpoint matches the bucket and region.
Region and endpoint mismatches are especially common with:
- copied scripts
- custom S3 clients
- S3-compatible tools
- multi-region deployments
- pre-signed URL generation
Also verify whether:
- S3 Transfer Acceleration
- custom VPC endpoints
- alternate S3 endpoints
are routing requests differently than the signing scope expects.
For example:
bucket.s3-accelerate.amazonaws.com
requires signing behavior aligned with the acceleration endpoint.
Step 3. Check System Clock Accuracy
AWS signatures are time-sensitive.
SigV4 generally allows a maximum clock skew of approximately 5 minutes.
If the client machine’s clock is too far off, the signed request may be rejected.
This commonly appears in:
- local laptops
- containers
- virtual machines
- build agents
- edge devices
- minimal Linux environments
Check time synchronization on the host.
On Linux:
timedatectl status
If the clock is wrong, enable or repair time synchronization before retrying.
Clock skew is one of the simplest causes to fix and one of the easiest to overlook.
Step 4. Inspect Pre-Signed URL Generation if Used
If the upload uses a pre-signed URL, the signed URL must match the actual upload request.
Check:
- HTTP method
- bucket
- key
- region
- content type
- signed headers
- expiration time
- checksum-related headers
A common failure occurs when the URL is signed for one request shape, but the browser or client sends a slightly different request.
Example:
- URL signed for
PUT - client sends
POST
Or:
- URL signed with one
Content-Type - browser sends another
Content-Type
Or:
- URL signed with a checksum or
Content-MD5 - client omits the required header
Those differences can break the signature.
Pre-signed URLs are exact-request tools.
Small mismatches matter.
Step 5. Look for Header or URL Changes After Signing
The signed request must not be changed after the signature is generated.
Common breaking changes include:
- proxy rewriting headers
- load balancer changing host headers
- browser adding or changing
Content-Type - URL encoding differences
- double-encoded paths
- spaces converted differently
- custom clients normalizing slashes
- middleware changing request headers
- Cloudflare or CloudFront header normalization
- reverse proxies stripping
X-Amz-*headers
For example, these may not sign the same way:
my report.pdf
and:
my%20report.pdf
The object key, headers, method, and endpoint must match what was signed.
If something changes between signing and sending, S3 recalculates a different signature.
When troubleshooting complex failures, review the:
- Canonical Request
- String-to-Sign
returned by S3 in the XML error response.
Those values often reveal the exact mismatch.
Step 6. Test with the AWS CLI or Official SDK
Before debugging custom signing code, test the same upload with the AWS CLI:
aws s3 cp file.txt s3://my-bucket/path/file.txt --region us-west-2
Or with an official AWS SDK.
If the AWS CLI succeeds but the custom client fails, the problem is likely in:
- request construction
- signing logic
- header handling
- URL encoding
- endpoint selection
- pre-signed URL generation
This comparison helps separate AWS-side configuration problems from client-side signing problems.
Pro Tips
SignatureDoesNotMatchoften means the request changed after it was signed- Region mismatches are one of the most common causes
- Pre-signed URLs are sensitive to HTTP method, headers, key, and expiration
- Proxies and gateways can break signatures by rewriting headers
- URL encoding differences can create extremely hard-to-see failures
- S3 Transfer Acceleration changes endpoint-signing behavior
- Always test with the AWS CLI or official SDK before blaming IAM
- Do not treat this like a normal
AccessDeniederror
Conclusion
The error:
An error occurred (SignatureDoesNotMatch) when calling the PutObject operation: The request signature we calculated does not match the signature you provided
means S3 rejected the upload because the signature AWS calculated did not match the signature sent by the client.
In modern AWS environments, the most common causes involve:
- wrong credentials
- wrong region
- incorrect endpoint
- clock skew
- pre-signed URL mismatches
- modified headers
- URL encoding differences
- custom signing errors
The fastest path to resolution is to verify credentials, confirm region and endpoint alignment, check request timing, inspect the Canonical Request details returned by S3, and compare the failing client against the AWS CLI or official SDK.
Aaron Rose is a software engineer and technology writer at tech-reader.blog.
Catch up on the latest explainer videos, podcasts, and industry discussions below.

