STS and credential errors
Look up an expired, invalid or rejected credential error by its text or code. Each entry gives the meaning, ranked causes with the check for each, and the fix.
markdownreferencev49H6Q-WAPMstage: operatetrust: officialtrust: fieldservice: stsinterface: cliinterface: sdkExpiredTokenInvalidClientTokenIdsecurity token expiredsecurity token invalidPackedPolicyTooLargeRegionDisabledMalformedPolicyDocumenttoken has expired
First, find out which identity is actually calling and where its credentials came from:
aws sts get-caller-identity --debug
The debug output names the credential source (environment variables, a profile in ~/.aws/credentials or ~/.aws/config, SSO, a role). Most errors on this page are the wrong or stale credentials being picked up first. Policy denials (is not authorized to perform) are a different problem: see reference/iam/errors.md.
ExpiredToken — The security token included in the request is expired
Means: the temporary credentials used to sign this request have passed their expiry.
Causes, most likely first:
- The session simply ran out. Credentials from AssumeRole last one hour unless a longer
DurationSecondswas requested, and cannot be renewed in place. Check: when the credentials were issued. - Stale values in environment variables.
AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEYandAWS_SESSION_TOKENare not refreshed by anything, and environment variables win over profiles. Check:printenv | grep AWS(Linux, macOS) orset AWS(Windows). - Stale cached credentials in the CLI cache. Check: the contents of
~/.aws/cli/cache. - The profile you meant is not the one in use. Check:
aws configure list --profile <name>. - The machine clock is wrong. A request that reaches AWS more than five minutes away from its own timestamp is rejected. Check: compare the system time with a reliable source.
Fix:
- Unset stale credential environment variables.
- Clear the CLI cache:
rm -r ~/.aws/cli/cache(Linux, macOS) ordel /s /q %UserProfile%\.aws\cli\cache(Windows). - Prefer a profile with
role_arnandsource_profile, so the CLI fetches fresh role credentials itself, instead of pasting credentials into files. - If sessions end too early for a long job, request a longer session with
DurationSeconds, up to the role's maximum session duration. Role chaining caps the session at one hour regardless. - Correct the system clock.
- Confirm with
aws sts get-caller-identity.
ExpiredToken returned by AssumeRoleWithWebIdentity
Means: a different problem with the same code. The STS API reference defines ExpiredToken (HTTP 400) as the web identity token you passed in being expired or invalid, not your own AWS credentials. You hit this in web-identity federation such as CI pipelines using OIDC (for example GitHub Actions).
Fix: obtain a new identity token from the identity provider and retry. Do not clear AWS credential caches; they are not involved.
The provided token has expired
Means: the login token behind an IAM Identity Center (SSO) or aws login profile has expired, so the CLI or SDK cannot fetch new short-term credentials.
Fix: sign in again: aws sso login --profile <name> for an Identity Center profile, or aws login for a console-credentials profile. With aws login, short-term credentials last 15 minutes and are refreshed automatically for up to 12 hours; after that a new login is required.
InvalidClientTokenId — The security token included in the request is invalid
Means: AWS does not recognise the access key ID used to sign the request.
Causes, most likely first:
- The access key was deleted, deactivated or never existed. Check: in the account, look up the access key ID the debug output shows.
- The credentials came from somewhere unexpected. The provider chain stops at the first source it finds, so an old key in an environment variable or the default profile shadows the one you meant. Check:
aws sts get-caller-identity --debugand read the source. - The key pair is mismatched or mistyped, for example a session token from one session with keys from another. Check:
aws_access_key_id,aws_secret_access_keyandaws_session_tokenin the profile all come from the same issuance. - The request went to a Region the account has not enabled (field reports; UNVERIFIED in official sources). Check: whether the target Region is an opt-in Region.
Fix: remove the stale source (unset environment variables, correct the profile), replace deleted keys, and prefer temporary credentials over long-term keys. Confirm with aws sts get-caller-identity --debug.
MalformedPolicyDocument (from AssumeRole)
Means: the session policy passed in Policy is not valid JSON policy, or contains characters outside the allowed range. HTTP 400; the message says what is wrong.
Fix: validate the JSON and the policy grammar. Session policy text may contain only tab, line feed, carriage return and characters from space through ÿ.
PackedPolicyTooLarge
Means: the session token would exceed its maximum size. Session policies and session tags both add to the token. HTTP 400. This can happen even when each individual limit is met: inline plus managed session policies within 2,048 characters, at most 10 managed policy ARNs, at most 50 session tags.
Fix: pass fewer or shorter session tags and session policies. Watch SessionTokenUtilization in the AssumeRole response (percentage of the maximum used); PackedPolicySize is deprecated.
RegionDisabled
Means: STS is not activated in the requested Region for the account that would issue the credentials. HTTP 403.
Fix: an administrator of that account activates STS for the Region in the IAM console, or the caller uses an STS endpoint in a Region where it is active.
Failures without a verified message string
These are documented failure conditions whose exact error text was not found in an official source. Search the hub with the text you hold; if you hold one of these, record the verbatim message in a drift report so this entry can be indexed.
DurationSecondsabove the role's maximum session duration. The call fails. Valid range is 900 to 43200 seconds, capped by the role's own setting.- Role chaining with
DurationSecondsabove one hour. The call fails; a chained session cannot exceed one hour. - Missing or expired MFA
TokenCodewhen the trust policy requires MFA. AssumeRole returns an access denied error; see the trust-policy entry inreference/iam/errors.md.
When none of these fits
Run aws sts get-caller-identity with the same credentials to confirm who you are. Read the role's trust policy (aws iam get-role --role-name <r> --query Role.AssumeRolePolicyDocument) against the caller's ARN, the external ID and the session tags. Then find the failed AssumeRole* event in CloudTrail (in the caller's account and Region) and read its errorMessage (guides/iam/fix-access-denied.md).