security token
request expiration
authentication error
API issues
access denial

The security token included in the request is expired

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

The error The security token included in the request is expired usually means the request is being signed with temporary credentials that are no longer valid. In AWS-heavy systems this often involves STS session credentials, assumed roles, or instance-profile credentials that were cached too long or generated on a machine with the wrong clock.

What the Error Really Indicates

Temporary credentials are made of three parts:

  • an access key ID
  • a secret access key
  • a session token

They also have an expiration time. Once that time passes, the request can no longer be authenticated, even if the access key and secret still look correct.

A fast first check is to confirm which credentials are active:

bash
aws sts get-caller-identity
aws configure list

If the command fails with the same expiration error, the problem is not your application code yet. It is the credential source.

Common Sources of Expired Tokens

The most common source is an assumed role session that was generated earlier and then reused after its expiration time. This often happens in local scripts, CI runners, and long-lived background processes.

Another common source is environment variables that override fresher credentials from the instance profile or shared config files. A stale AWS_SESSION_TOKEN can silently win over a valid role-based credential source.

Clock skew is another real cause. If the local system clock is significantly wrong, a token that is technically valid can appear expired or not yet valid when the request is signed.

Refresh the Credential Source Instead of Retrying Blindly

If the credentials came from aws sts assume-role, request a new session and export the fresh values.

bash
aws sts assume-role \
  --role-arn arn:aws:iam::123456789012:role/DeployRole \
  --role-session-name local-debug

If the credentials are in environment variables, clear them and retry so the SDK can fall back to the intended provider chain:

bash
unset AWS_ACCESS_KEY_ID
unset AWS_SECRET_ACCESS_KEY
unset AWS_SESSION_TOKEN

Then test again:

bash
aws sts get-caller-identity

On EC2, ECS, EKS, and Lambda, the better long-term fix is usually to rely on attached IAM roles instead of hard-coded temporary credentials. The AWS SDKs know how to refresh role-based credentials automatically.

Handle Refresh Correctly in Application Code

For application code, avoid building a credential refresh system by hand unless you really need to. Let the AWS SDK manage it through the default credential chain or a supported provider.

A simple boto3 example using the default provider chain is:

python
1import boto3
2
3session = boto3.Session()
4s3 = session.client("s3")
5response = s3.list_buckets()
6print([bucket["Name"] for bucket in response["Buckets"]])

This works best when the environment provides refreshable credentials through a profile, IAM role, or AWS SSO configuration.

If you manually inject temporary credentials into code, you also take responsibility for renewing them before expiration. That is where many long-running services fail.

Do Not Ignore Clock Synchronization

If tokens are expiring immediately or failing inconsistently across hosts, check the system clock. AWS request signing is time-sensitive, and significant skew can break otherwise healthy credentials.

bash
date -u

On servers, make sure time synchronization such as chrony or another NTP client is running correctly. In containerized environments, verify the host clock because containers usually inherit host time.

Common Pitfalls

A common mistake is rotating only the access key and secret but forgetting the session token. Temporary AWS credentials are a set, and all pieces must belong to the same session.

Another mistake is retrying the same request with the same expired credentials. Retries help transient network issues, but they do not revive an expired token.

Developers also get tripped up by stale environment variables. A shell session can keep old credentials active even after a user logs in again through AWS SSO or assumes a fresh role elsewhere.

Finally, do not overlook clock skew. It is less common than stale credentials, but when it happens the error message looks almost identical.

Summary

  • The error usually means temporary credentials have passed their expiration time.
  • Check the active credential source before debugging application logic.
  • Refresh assumed-role sessions instead of retrying with the same token.
  • Clear stale environment variables that may override valid credentials.
  • Use role-based or SDK-managed credential providers whenever possible.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.