How can I troubleshoot the AWS STS error “the security token included in the request is expired” when using the AWS CLI to assume an IAM role?

Last updated: 2022-05-17

I tried to assume an AWS Identity and Access Management (IAM) role by using the AWS Command Line Interface (AWS CLI). However, I received an error similar to the following:

"The security token included in the request is expired."

Short description

Temporary security credentials for IAM users are requested using the AWS Security Token Service (AWS STS) service. Temporary credentials created with the AssumeRole API action last for one hour by default. After temporary credentials expire, they can't be reused. For more information, see Temporary security credentials in IAM.

Resolution

Use the following troubleshooting steps for your use case.

If you receive errors when running AWS CLI commands, make sure that you’re using the most recent AWS CLI version.

Make sure that your temporary security credential requests can reach AWS endpoints

Establishing credentials for a role requires an access key ID, secret access key, and session token. Requests sent must reach the AWS endpoint within five minutes of the timestamp on the request or the request is denied. For more information, see Why requests are signed.

Using profiles to assume an IAM role

A named profile is a collection of settings and credentials that you can apply to an AWS CLI command. You must verify that you're using the correct credentials.

The following AWS CLI command uses the default profile credentials:

aws s3 ls

This example command uses the project1 profile credentials configured in the .config file:

aws s3 ls --profile project1

Example output using expired credentials:

"An error occurred (ExpiredToken) when calling the ListBuckets operation: The provided token has expired."

These profiles are defined in your .aws folder containing the .credentials and .config files.

The config file is located at ~/.aws/config for Linux/macOS and C:\Users\%USERPROFILE%\.aws\config for Windows. The credentials file is located at ~/.aws/credentials for Linux/macOS and C:\Users\%USERPROFILE%\.aws\credentials for Windows.

To check your default profile credentials, run the following command:

aws configure list --profile default

Example output:

Name Value Type Location
---- ----- ---- --------
profile default manual —profile
access_key TGN7 shared-credentials-file
secret_key SbXb shared-credentials-file
region us-east-1 config-file ~/.aws/config

To confirm that the same credentials are used for the profile project1, run the following command:

aws configure list --profile project1

Example output:

Name Value Type Location
---- ----- ---- --------
profile project1 manual —profile
access_key QN2X config-file
secret_key LPYI config-file
region eu-west-1 config-file ~/.aws/config

In the example output, note that different credentials might be configured for the default and project1 profiles.

You can create a profile in your .aws/config file using the following format:

[profile project1]
region = eu-west-1
aws_access_key_id = <access-Key-for-an-IAM-role>
aws_secret_access_key = <secret-access-Key-for-an-IAM-role>
aws_session_token = <session-token>

These credentials are provided to you when you run the AWS STS assume-role command similar to the following:

aws sts assume-role --role-arn arn:aws:iam::<account-number>:role/Prod-Role --role-session-name environment-prod

Example output:

{
"AssumedRoleUser": {
"AssumedRoleId": "AROAXXXXXXXXXXXX:environment-prod",
"Arn": "arn:aws:sts::<account-number>:assumed-role/Prod-Role/environment-prod"
},
"Credentials": {
"SecretAccessKey": "<secret-access-Key-for-an-IAM-role>,
"SessionToken": "<session-token>",
"Expiration": "2020-03-31T17:17:53Z",
"AccessKeyId": "<access-Key-for-an-IAM-role>"
}

Note: You can increase the maximum session duration expiration for temporary credentials for IAM roles using the DurationSeconds parameter for your use case.

The new assume-role API call then retrieves a new set of valid credentials. Following the API call, you must manually update the ~/.aws/config file with the new temporary credentials.

You can avoid updating the config file every time a session expires. Define a profile for the IAM role along with the user that assumes the role in the ~/.aws/config or ~/.aws/credentials file similar to the following:

[profile project1]
role_arn = <arn-of-IAM-role>
source_profile = user1
region = <region>

Note that user1 is defined in your ~/.aws/credentials file similar to the following:

[user1]
aws_access_key_id=AKIAIOSFODNN7EXAMPLE
aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

Defining the source_profile means that you don't have to update your temporary credentials in the ~/.aws/config or ~/.aws/credentials file.

The following AWS CLI command lists the Amazon Simple Storage Service (Amazon S3) buckets with credentials for user1 located in the ~/.aws/credentials file.

aws s3 ls --profile project1

If you're using the AWS CLI with a source_profile element, the API call assume-role puts credentials in the .aws/cli/cache file. Expired credentials are automatically updated in the .aws/cli/cache file. If you receive an error for expired credentials, you can clear the cache with the following commands:

Linux/macOS:

$ rm -r ~/.aws/cli/cache

Windows:

C:\> del /s /q %UserProfile%\.aws\cli\cache

The AWS CLI creates new credentials in the cache.

Create environment variables to assume the IAM role and then verify access

You can use IAM role credentials to create three environment variables to assume the IAM role similar to the following:

Linux/macOS:

export AWS_ACCESS_KEY_ID=RoleAccessKeyID
export AWS_SECRET_ACCESS_KEY=RoleSecretKey
export AWS_SESSION_TOKEN=RoleSessionToken

Windows:

C:\> setx AWS_ACCESS_KEY_ID RoleAccessKeyID
C:\> setx AWS_SECRET_ACCESS_KEY RoleSecretKey
C:\> setx AWS_SESSION_TOKEN RoleSessionToken

To verify that you assumed the correct IAM role, run the following command:

aws sts get-caller-identity

The get-caller-identity command displays information about the IAM identity used to authenticate the request. For more information, see How do I assume an IAM role using the AWS CLI?

Environment variables hold temporary cached credentials even after they expire and aren't renewed automatically. Use the following commands to check if credential environment variables are set:

Linux/macOS:

$ printenv | grep AWS

Windows:

C:\>set AWS

You can remove expired environment variables with the following commands:

Linux/macOS:

$ unset AWS_ACCESS_KEY_ID
$ unset AWS_SECRET_ACCESS_KEY
$ unset AWS_SESSION_TOKEN

Windows:

C:\>set AWS_ACCESS_KEY_ID=
C:\>set AWS_SECRET_ACCESS_KEY=
C:\>set AWS_SESSION_TOKEN=

You can now use the assume-role API call again to get new, valid credentials and set the environment variables again.

Important: The .aws/credentials and .aws/config files contain credential details for your IAM entities. When managing your credentials, make sure that you follow security best practices in IAM.