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.


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.