The security token included in the request is invalid
TL;DR — Your AWS credentials are wrong, expired, or the SDK is reading a different set than you think. Refresh/verify the access key + secret (and session token if using temporary credentials), and confirm which profile/source the SDK is actually using.
What it means
UnrecognizedClientException: The security token included in the request is invalid.AWS rejected your credentials at authentication — before checking permissions. This is different from AccessDeniedException, which means the credentials are valid but lack permission. Here the credentials themselves aren't accepted. The exception name varies by tool: the AWS CLI shows the same message under InvalidClientTokenId, and DynamoDB's error reference words its UnrecognizedClientException entry as "The Access Key ID or security token is invalid." — they all mean authentication failed.
Why it happens
- Expired temporary credentials — an STS/SSO session or assumed-role token timed out, or you have an access key without the required
AWS_SESSION_TOKEN. - Wrong or partial keys — a typo, a rotated/deleted access key, or
AWS_ACCESS_KEY_IDset without a matchingAWS_SECRET_ACCESS_KEY. - A stale
AWS_SESSION_TOKENleft in the environment from a previous session. - Pointing real credentials at DynamoDB Local (or vice-versa) — Local accepts any dummy keys but a real endpoint won't accept placeholders.
- Clock skew on the machine large enough to invalidate the request signature.
How to fix it
- Verify the credentials work:
aws sts get-caller-identity. If that fails too, it's the credentials, not DynamoDB. - Refresh temporary credentials — re-run
aws sso login/ re-assume the role, and make sureAWS_SESSION_TOKENis set for temporary keys. - Clear stale env vars — an old
AWS_SESSION_TOKEN/AWS_ACCESS_KEY_IDin your shell overrides your profile. Unset them or set the right profile (aws configure listshows which source is winning). - For DynamoDB Local, use placeholder creds and point at the local endpoint:
const client = new DynamoDBClient({ region: 'local', endpoint: 'http://localhost:8000', credentials: {accessKeyId: 'local', secretAccessKey: 'local'} }); - Check the machine clock is accurate (NTP-synced) if everything else looks right.
From DynoTable
DynoTable resolves your ~/.aws profile fresh on every connection,
so a re-login, key rotation, or cleared env var is picked up without restarting
the app. Press ⌘P to see which profile is active and whether its
credential dot is green — a red dot means Sign in (SSO) or Reconnect
before any table call will succeed. For DynamoDB Local, add a profile with endpoint
http://localhost:8000 and alphanumeric placeholder keys (see
Running DynamoDB Local); real AWS keys against Local
trigger this same error.
FAQ
What does "The security token included in the request is invalid" mean? AWS rejected your credentials at authentication, before checking permissions. The keys are wrong, rotated, or partial, a temporary session token is expired or stale, or the SDK is reading a different credential source than you think.
How do I debug an invalid security token?
Run aws sts get-caller-identity — if that fails too, it's the credentials, not DynamoDB. Refresh temporary credentials (aws sso login or re-assume the role), make sure AWS_SESSION_TOKEN is set for temporary keys, and clear stale env vars that override your profile.
Reproduce it
This one needs no valid credentials and no local engine — authentication fails before authorization, so the real DynamoDB service answers a deliberately bogus key:
import boto3
boto3.client(
'dynamodb',
region_name='us-east-1',
aws_access_key_id='AKIAIOSFODNN7EXAMPLE',
aws_secret_access_key='wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
).list_tables()Real output:
UnrecognizedClientException: The security token included in the request is invalid. [HTTP 400]A structurally malformed key (not-a-key) returns the identical message, which is the practical trap: the error tells you the credential was rejected, never why. A typo, a deleted access key, a key from the wrong account and a key that never existed all land here identically. Compare it with security token expired, which does distinguish itself, and note the pairing — the wire code is UnrecognizedClientException while the message talks about a "security token", so searching the message and grepping your handler for the class need different strings.
Related errors
- AccessDeniedException — valid credentials, missing permission.
- Missing region in config
- Learn: Running DynamoDB Local — placeholder credentials against a local endpoint.
Sources
- Troubleshooting errors for the AWS CLI — AWS CLI User Guide (verified 2026-07-13)
- Error handling with DynamoDB — Amazon DynamoDB Developer Guide (verified 2026-07-13)
- DynamoDB local usage notes — Amazon DynamoDB Developer Guide (verified 2026-07-13)
Reproduced 2026-07-26 against the live DynamoDB service in us-east-1 via boto3 1.43.56 — the output above is verbatim.