AWS SES 403 "SignatureDoesNotMatch" in CI
AWS returns HTTP 403 SignatureDoesNotMatch when the SigV4 signature computed by the client does not match what SES expects. The usual CI causes are a wrong or truncated secret access key, a clock skew, or signing for a different region than the endpoint.
What this error means
A SES call fails with SignatureDoesNotMatch: The request signature we calculated does not match the signature you provided. It fails consistently once the credentials or region are wrong.
An error occurred (SignatureDoesNotMatch) when calling the SendEmail operation:
The request signature we calculated does not match the signature you provided.
Check your AWS Secret Access Key and signing method.Common causes
Wrong or truncated secret access key
A AWS_SECRET_ACCESS_KEY secret with a trailing newline or a partial paste signs requests incorrectly.
Region mismatch when signing
Signing for one region while hitting another endpoint invalidates the signature.
How to fix it
Provide correct credentials and region
- Store
AWS_ACCESS_KEY_IDandAWS_SECRET_ACCESS_KEYas secrets without stray whitespace. - Set
AWS_REGIONto the region where SES is configured. - Prefer short-lived credentials via OIDC where possible.
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: us-east-1Use OIDC role assumption
Assume a role with the official AWS action so no long-lived keys are stored or mistyped.
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/ci-ses
aws-region: us-east-1How to prevent it
- Store AWS keys without trailing whitespace, or use OIDC instead.
- Keep
AWS_REGIONaligned with the SES endpoint. - Rotate access keys and update secrets in one place.