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 cp
  • aws 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

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

  1. Verify the active AWS identity and credentials
  2. Confirm the bucket region and endpoint
  3. Check system clock accuracy
  4. Inspect pre-signed URL generation if used
  5. Look for header or URL changes after signing
  6. 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

  • SignatureDoesNotMatch often 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 AccessDenied error

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.


Popular posts from this blog

Insight: The Great Minimal OS Showdown—DietPi vs Raspberry Pi OS Lite

Running AI Models on Raspberry Pi 5 (8GB RAM): What Works and What Doesn't

Raspberry Pi Connect vs. RealVNC: A Comprehensive Comparison