AWS: SignatureDoesNotMatch / InvalidClientTokenId — the request signature we calculated does not match
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
- Re-copy or rotate the key pair
- Sync time (NTP)
- Use the bucket’s actual region
- For presigned PUTs, send exactly the Content-Type you signed
Detailed fix by platform
AWS
- 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
- Key pair — ID and secret from the same pair?
- Clock — Server time correct?
- Region — Signing region = resource region?
- Presigned — Same method/headers as signed?
🧠 Still stuck? Analyze your error
Paste the full message, response headers or stack trace — we'll detect the platform and point to the most likely cause.
Was this page helpful?
Report a correction or suggest an improvement
Last updated 2 Oct 2026