I used an Amazon Simple Storage Service (Amazon S3) presigned URL to make requests to my Amazon S3 bucket, and I received a "SignatureDoesNotMatch" error message with an "HTTP 403 Forbidden" response code.
Short description
When you generate a presigned URL, the client calculates a unique signature to authenticate the request. Then, Amazon S3 calculates a signature based on the parameters that the client sends in the HTTP request and compares both signatures. If the signatures don't match, then you receive a "SignatureDoesNotMatch" error with an "HTTP 403 Forbidden" response code.
Resolution
Note: If you receive errors when you run AWS Command Line Interface (AWS CLI) commands, then see Troubleshooting errors for the AWS CLI. Also, make sure that you're using the most recent AWS CLI version.
Validate the HTTP action
If you generate a presigned URL, then you assign an HTTP action to the URL. Make sure that the action that the client sends in the HTTP request matches the HTTP action in the URL. For example, if you assign the GET action to the URL, then the action in the request must have the GET HTTP action.
Check that you used the correct secret access key to generate the presigned URL
Check that the code that generated the presigned URL has the correct secret access key. Make sure that there isn't any extra spaces or wrong characters.
If you use the AWS CLI to generate your presigned URL, then configure the credentials with the correct secret access key. Run the cat command to get the current credentials:
cat ~/.aws/credentials
If it's a temporary session, then check that the AWS_SESSION_TOKEN is correct. Verify that no extra spaces or wrong characters passed in the secret access key from when you generated your presigned URL.
Verify that the secret access key in your credentials matches your original secret access key.
Verify that the bucket name and object name match the values in the URL
Verify that the bucket name and object name are correct and match the names that are in the signature generation of the URL.
Verify that the headers correctly generated in the HTTP request
Make sure that the HTTP headers that generate the signature match the headers that the client sends to Amazon S3 in the HTTP request. You must include in your request any headers that you use to sign the URL. The presigned URL contains only the host, path, and query parameters.
If you added a ContentType parameter when you generated a presigned URL, then pass a Content-type header when you send requests for the presigned URL. For example, run the following curl command:
curl -X PUT -T "abcd-video.mp4" -H "Content-Type: video/mp4" "Your-presigned-url"
Note: Replace Your-presigned-url with your presigned URL.
Then, make sure that the value of the header matches the value that you generated when you calculated the signature.
Confirm that the AWS Region is correct
Before you send the presigned URL to Amazon S3, confirm that your Region for the URL matches the current Region of the bucket.
Run the GetBucketLocation API command to check the Region of an S3 bucket. Or, run the get-bucket-location AWS CLI command to verify the Region:
aws s3api get-bucket-location --bucket example-bucket
Note: Replace example-bucket with your bucket name.
Example output:
{
"LocationConstraint": "us-west-2"
}
Check that the system time is correctly set in a valid period
If you set the system time to a future date after the digital signature's validity period, then the signature appears as expired and fails. If you set the system time to a past date before the signature's validity period, then the signature isn't valid and fails.
Related information
Why does the presigned URL for my Amazon S3 bucket expire before the expiration time that I specified?
Download and upload objects with presigned URLs
How do I troubleshoot the error "Request has expired" when I try to access an S3 object?