Home / Tutorials / AWS

AWS · Cloud · Degraded

Fix: ExpiredToken: The provided token has expired

Error ExpiredToken: The provided token has expired.

By the Erzon engineering team · A step-by-step fix, not a forum thread

An AWS call that worked earlier now fails with ExpiredToken: The provided token has expired. This is the most benign of the AWS credential errors: your identity is valid, but the temporary session behind it has run out. Temporary credentials from STS, IAM Identity Center (SSO), or an assumed role always carry an expiry, and once that time passes every signed request is rejected until you refresh. The quick fix is to log in or re-assume the role again. The lasting fix is to stop caching a single token and let the SDK refresh credentials for you.

ExpiredToken: The provided token has expired.

What this error means

Unlike long-lived IAM access keys, temporary credentials come with a session token and a hard expiry timestamp. They are issued by STS when you assume a role, by IAM Identity Center when you log in through SSO, or by an instance or container role. Each session lasts for a bounded duration (from fifteen minutes up to a configured maximum). Once the expiry passes, AWS rejects any request signed with those credentials and returns ExpiredToken. Nothing is broken and no permission changed: the session simply ended. The reason it often surfaces unexpectedly is that a laptop went to sleep, a long-running job outlived its session, or an application cached the credentials once at startup and never refreshed them.

Common causes

  • An SSO login session or role session reached its configured duration.
  • A laptop slept or a job ran longer than the session lifetime, so the token expired mid-work.
  • An application read the access key, secret, and session token once into variables and reused them past expiry instead of refreshing.
  • A CI pipeline assumed a role at the start of a long run and the credentials expired before the run finished.
  • A cached SSO token on disk went stale and was not renewed.

How to fix it

STABILIZE

  1. Refresh interactively for whatever issued the session. If you use IAM Identity Center, log in again to renew the cached session:
aws sso login --profile my-profile
  1. Confirm the refreshed credentials work by identifying the caller:
aws sts get-caller-identity --profile my-profile

DIAGNOSE

  1. Determine how the session was issued so you refresh the right way. Check what the profile is configured to do:
aws configure list --profile my-profile

Look for whether it resolves through SSO, an assumed role (role_arn with a source_profile), or static keys with a session token.

  1. If the credentials come from an explicit assume-role call rather than a profile, re-assume the role to get a fresh session and note the new expiry:
aws sts assume-role \
  --role-arn arn:aws:iam::123456789012:role/deploy-role \
  --role-session-name refresh-$(date +%s) \
  --query 'Credentials.Expiration'
  1. If this is happening inside an application, check whether the code caches credentials at startup. Credentials pinned into environment variables or globals once, then reused, are the classic cause.

FIX

  1. For local and CLI use, prefer a profile that the CLI can refresh on its own. A profile configured for SSO or with a role_arn and source_profile will renew automatically when you have a valid base session, so you only re-login when the base session ends.
  2. For applications, use the SDK default credential provider chain instead of hardcoding a token. In Python with boto3, create a client with no explicit credentials and let botocore resolve and refresh them:
import boto3

# No keys passed in: the default provider chain resolves the role,
# instance profile, or SSO cache and refreshes before expiry.
s3 = boto3.client("s3")
s3.list_buckets()
  1. Remove any code that copies aws_access_key_id, aws_secret_access_key, and aws_session_token into long-lived variables. If you must pass a role, use the SDK’s assume-role provider (for example botocore’s AssumeRoleProvider via a shared config profile) so refresh is handled for you.
  2. For long CI jobs, either extend the session duration to comfortably exceed the run, or re-assume the role in the steps that run near or past the original expiry.

How to prevent it

  • Always resolve credentials through the SDK default provider chain in application code so they refresh automatically.
  • Never cache the session token for the life of a process; treat temporary credentials as short-lived by design.
  • Size role session durations to the work: long enough for the job, not so long that they become de facto permanent.
  • For long pipelines, refresh or re-assume within the run rather than once at the start.
  • Automate aws sso login prompts in developer tooling so an expired local session is a one-command fix.

When to call a senior engineer

Call for help when production services intermittently fail with ExpiredToken and you cannot find where credentials are being cached, when a role-chaining or federation setup keeps handing out sessions that expire mid-request, or when refreshing credentials safely across a fleet of long-running workers is not obvious. Erzon engineers can rework the credential handling so the SDK refreshes for you, remove the cached-token anti-pattern, and make expiring sessions a non-event instead of an outage.

Related errors we fix

Still down after this?

Want a senior engineer to just fix it?

Paste this exact error into the form. A senior engineer replies within one business hour with what is likely wrong and a flat quote. Triage is free.

Book a fix

← Back to all error fixes

Still down?

Get a senior engineer on it now

Leave your email and a line about what is happening. A senior engineer replies within one business hour with what is likely wrong and a flat quote. Triage is free.

Or email [email protected]. Same engineers, same one-hour clock.