# AWS: SignatureDoesNotMatch / InvalidClientTokenId — the request signature we calculated does not match

**Code:** `SignatureDoesNotMatch` · **Category:** AWS · **Seen on:** AWS, JavaScript

AWS rejected the request signature — wrong secret key, wrong region, clock skew, or a presigned URL used differently from how it was signed.

## Meaning

Every AWS request is signed with your secret key (SigV4) over the method, path, headers and timestamp. A wrong secret, an extra/changed header, the wrong region or a clock more than ~5 minutes off all break the signature. `InvalidClientTokenId` means the access key ID itself isn’t recognised.

## Common causes

- Secret key copied with extra spaces/characters
- Access key and secret from different pairs / accounts
- System clock skew
- Wrong region for the endpoint
- Presigned S3 URL used with different method or Content-Type than signed
- Special characters in object keys not encoded consistently

## Quick fix

1. Re-copy or rotate the key pair
2. Sync time (NTP)
3. Use the bucket’s actual region
4. For presigned PUTs, send exactly the Content-Type you signed

## Detailed fix by platform

### AWS

1. Presigned PUT must match the signed Content-Type:

```javascript
const url = await getSignedUrl(s3, new PutObjectCommand({ Bucket: 'uploads', Key: key, ContentType: 'image/png' }), { expiresIn: 300 });
await fetch(url, { method: 'PUT', headers: { 'Content-Type': 'image/png' }, body: file });
```


## How to diagnose

1. **Key pair** — ID and secret from the same pair?
2. **Clock** — Server time correct?
3. **Region** — Signing region = resource region?
4. **Presigned** — Same method/headers as signed?

---
Source: [WhatIsMyError](https://whatismyerror.com/errors/aws/signaturedoesnotmatch)
