AWS `InvalidClientTokenId`: What It Means and How to Fix It
InvalidClientTokenId is AWS not recognising the access key at all — deleted, deactivated, or from the wrong partition. It comes from STS, and the message reads:
The security token included in the request is invalid.
If you are here mid-incident, skip to how to tell which cause you have — the command there narrows it down faster than reading the list.
Quick reference
| Error | InvalidClientTokenId |
| Service | STS |
| Message | The security token included in the request is invalid. |
| Most common cause | The access key was deleted or deactivated |
What it actually means
This is distinct from ExpiredToken and from SignatureDoesNotMatch. AWS is saying it does not recognise the access key ID itself.
The three failures form a useful ladder: InvalidClientTokenId means the key does not exist, SignatureDoesNotMatch means it exists but the secret is wrong, and ExpiredToken means it existed and has expired.
Why it happens
Ranked by how often each one turns out to be the answer.
| # | Cause | Fix |
|---|---|---|
| 1 | The access key was deleted or deactivated | Check with aws iam list-access-keys --user-name <user> from a working identity. |
| 2 | The IAM user was deleted | Keys die with the user. |
| 3 | Credentials belong to a different partition | Keys from a commercial account do not work against aws-us-gov or aws-cn endpoints, and vice versa. |
| 4 | A stale AWS_SESSION_TOKEN is set in the environment |
A leftover session token from an earlier assume-role poisons a request that is otherwise using valid long-lived keys. unset AWS_SESSION_TOKEN. |
| 5 | A partially-populated credential set | One of AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_SESSION_TOKEN set and the others not, so the SDK mixes environment and profile credentials. |
How to tell which one you have
# Which credentials is the SDK actually using, and from where?
aws sts get-caller-identity --debug 2>&1 | grep -i 'credentials found|Looking for credentials'
# Is a stale session token lurking?
env | grep AWS_
# Confirm the key exists (from a different, working identity)
aws iam list-access-keys --user-name my-user
Credential precedence trips people constantly: environment variables beat the shared credentials file, which beats the instance profile. An environment variable set in one shell three hours ago is a real cause.
Preventing it
Prefer a named profile over environment variables, so the source is explicit and inspectable. Where environment variables are necessary, set all three or none.
Rotate to role-based credentials — instance profiles, IRSA, OIDC in CI — and the whole class disappears.
Related errors
ExpiredToken— STSSignatureDoesNotMatch— All AWS APIs- All AWS error references — the full index
Quota codes, limits and behaviour on this page were last checked against AWS documentation on 2026-08-22. AWS changes these; if something here does not match what you are seeing, trust the console and tell us.