How do I troubleshoot "SignatureDoesNotMatch" or "403 Forbidden" errors for Amazon S3 presigned URL requests?

3 minute read
1

I used an Amazon Simple Storage Service (Amazon S3) presigned URL to make requests to my Amazon S3 bucket, and I received an "SignatureDoesNotMatch" or "403 Forbidden" error message.

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 the "SignatureDoesNotMatch" error.

Resolution

To troubleshoot this issue, check the following configuration settings for your Amazon S3 presigned URL request.

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 method

When you generate a presigned URL, 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 HTTP action in the request must also be GET.

Check the secret access key

Check whether the secret access key that you used to generate the presigned URL is in the Incorrect, Not valid, or Turned off state. The secret access key enters into one of these states when you add mismatched characters or incorrect spacing to the secret access key. Check that you're using the correct access key to regenerate the presigned URL.

Verify the bucket name and key name in the URL

Verify that the bucket name and object name are correct and match the ones that are in the signature generation of the URL. The name case must also match.

Verify the headers that are used in HTTP request

Make sure that the HTTP headers that you use to generate the signature match the headers that the client sends to S3 in the HTTP request.

Also, make sure that the value of the header matches the value that's generated during signature calculation. 

Confirm that the AWS Region is correct

Before you send the presigned URL to S3, confirm that the AWS Region where you generated the URL matches the Region where the bucket currently exists.

Run the GetBucketLocation API request to check the Region of an S3 bucket. You can also run the get-bucket-location AWS CLI command:

$ aws s3api get-bucket-location --bucket example-bucket

Example output:

{      
"LocationConstraint": "us-west-2"  
}

Check the system time validity period

If you set the system time to a future date after the validity period of the digital signature, 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

List of error codes

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?

AWS OFFICIAL
AWS OFFICIALUpdated 4 months ago
2 Comments

This article is frustratingly vague. For example it suggests to "check the secret access key" but gives zero information on how to do that.

replied 6 days ago

The vagueness of "Make sure that the HTTP headers that you use to generate the signature match the headers that the client sends to S3 in the HTTP request"... okay there are about 16 headers in each request, which ones SPECIFICALLY are you validating? I've tried 439 different combinations and I REPEATEDLY get the SignatureDoesNotMatch error. Oh yeah, and the boto client throws an error when I add the ContentType param to the generate_presigned_url request.

replied 6 days ago