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_ID set without a matching AWS_SECRET_ACCESS_KEY.
  • A stale AWS_SESSION_TOKEN left 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

  1. Verify the credentials work: aws sts get-caller-identity. If that fails too, it's the credentials, not DynamoDB.
  2. Refresh temporary credentials — re-run aws sso login / re-assume the role, and make sure AWS_SESSION_TOKEN is set for temporary keys.
  3. Clear stale env vars — an old AWS_SESSION_TOKEN/AWS_ACCESS_KEY_ID in your shell overrides your profile. Unset them or set the right profile (aws configure list shows which source is winning).
  4. 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'}
    });
  5. 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.

Sources

Reproduced 2026-07-26 against the live DynamoDB service in us-east-1 via boto3 1.43.56 — the output above is verbatim.

Work with DynamoDB without the Console

A fast DynamoDB desktop client that runs the real SQL DynamoDB can’t — JOINs, GROUP BY, aggregates — with visual editing and an AI agent on your own Bedrock keys.

Free 30-day trial, no credit card — then the Free plan with no time limit.