AWS InvalidClientTokenId: The security token is invalid
Encountering AWS InvalidClientTokenId means your security token is invalid, often due to expired or malformed credentials; this guide explains how to troubleshoot and fix it.
What This Error Means
The InvalidClientTokenId: The security token is invalid error from AWS signifies a fundamental authentication failure. In simpler terms, AWS doesn't recognize the credentials you're presenting. This isn't a permissions error, meaning it's not about what you're allowed to do (authorization), but rather who you are (authentication). AWS cannot verify your identity based on the Access Key ID and Secret Access Key provided. When you hit this, the AWS service you're trying to interact with has received a request signed with an access key ID that it doesn't consider valid, either because it's malformed, expired, or simply doesn't exist.
Why It Happens
At its core, this error means AWS couldn't match the AWS_ACCESS_KEY_ID in your request to a valid, active set of credentials. Every interaction with an AWS service requires a signed request, and that signature relies on a valid access key and secret key pair. If any part of this authentication process goes awry – the keys are wrong, they've expired, or there's a mismatch in how the request is signed – you'll be greeted by InvalidClientTokenId. In my experience, this usually points to an issue with how credentials are being managed or retrieved by the client application or CLI.
Common Causes
This error often crops up in a few predictable scenarios. Understanding these common causes is the first step towards a quick resolution.
Expired Temporary Credentials
This is, hands down, the most frequent culprit. AWS IAM roles and AWS Security Token Service (STS) calls (like aws sts assume-role) provide temporary credentials consisting of an AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and crucially, an AWS_SESSION_TOKEN. These credentials have a limited lifespan, typically ranging from 15 minutes to 12 hours. If your application or CLI session tries to use these credentials after their expiration, you'll see InvalidClientTokenId. I've seen this in production when an automated script relying on assumed roles wasn't properly refreshing its tokens.
Incorrect or Malformed Credentials
Typos happen. Copy-pasting errors are common. If your AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY is incorrect, truncated, or contains extra characters (like leading/trailing spaces), AWS won't be able to validate them. This can occur when manually configuring credentials in ~/.aws/credentials, setting environment variables, or even hardcoding them (which, by the way, is a bad practice you should avoid).
Wrong Default Region or Explicit Region Mismatch
While credentials themselves aren't region-specific, the services you're trying to access are. Sometimes, the InvalidClientTokenId error can appear when your credentials are valid, but you're trying to interact with a service in a region where those specific credentials (or the IAM user/role they belong to) don't have access or aren't intended to be used. More commonly, it happens when you provide credentials that are only valid for a specific STS endpoint, and your client is configured to hit a different region's endpoint. Though less direct, I've seen misconfigured regions lead to confusing authentication failures.
System Clock Skew
AWS requests are cryptographically signed, and part of that signature often includes a timestamp. If your system's clock is significantly out of sync with AWS's servers (even by a few minutes), AWS might reject your request because the timestamp in the signature appears to be in the future or too far in the past. While less common with modern operating systems that synchronize time automatically, it's a subtle cause that can be tricky to diagnose if you're not aware of it.
IAM User or Role Deleted/Deactivated
If the underlying IAM user or role to which the AWS_ACCESS_KEY_ID belongs has been deleted, deactivated, or its access keys have been rotated/deactivated in the AWS console, any attempts to use those older, now-invalid keys will result in this error. This often happens during security cleanups or user offboarding processes.
Step-by-Step Fix
Troubleshooting InvalidClientTokenId requires a systematic approach. Here's how I typically go about resolving it:
-
Check Your Active Credentials (AWS CLI First)
Start by understanding what credentials your AWS CLI or SDK is currently configured to use.
bash aws configure list
Look at theaccess_key,secret_key, andregionfields. Pay close attention to thetypefield; if it saysassume-roleorsso, you're using temporary credentials, which makes expiration a prime suspect. -
Verify Environment Variables
Environment variables (likeAWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY,AWS_SESSION_TOKEN, andAWS_DEFAULT_REGION) take precedence over~/.aws/credentialsand~/.aws/config. Check if any are set that might be overriding your intended configuration.
bash printenv | grep AWS_
IfAWS_SESSION_TOKENis present, you are definitely using temporary credentials. Its absence withAWS_ACCESS_KEY_IDandAWS_SECRET_ACCESS_KEYusually means static credentials are in use. -
Inspect
~/.aws/credentialsand~/.aws/config
Manually open these files and check for:- Typos in
aws_access_key_idoraws_secret_access_key. - Extra spaces around the key values.
- The presence of
aws_session_tokenif you expect temporary credentials. - Correct
regionsettings for your profiles.
Example of
~/.aws/credentials:
```ini
[default]
aws_access_key_id = AKIAIOSFODNN7EXAMPLE
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY[my-temp-profile]
aws_access_key_id = ASIAV4EXAMPLE2N2K4R32
aws_secret_access_key = L62YEXAMPLEw4Q+hJ70dEAXPLezT95DPMU
aws_session_token = IQoJb3JpZ2luX2VjEL...
``` - Typos in
-
Test with
aws sts get-caller-identity
This is your best friend for credential validation. It attempts to resolve your identity without interacting with any other service.
bash aws sts get-caller-identity
If this command succeeds, your credentials are valid, and the problem likely lies with the specific service you were trying to access (e.g., region mismatch, service-specific IAM policy issues that look like an authentication error but aren't). If it fails withInvalidClientTokenId, your credentials are indeed the problem. -
Refresh Temporary Credentials
Ifaws sts get-caller-identitypoints to an issue andAWS_SESSION_TOKENwas present (oraws configure listshowedtype = assume-role/sso), your temporary credentials have likely expired.- If using AWS SSO: Run
aws sso loginagain. - If assuming a role: Re-run your
aws sts assume-rolecommand to generate fresh tokens. - If using an EC2 instance profile: You usually don't need to do anything manually, as the instance profile mechanism handles refresh automatically. If you're seeing this error on EC2, it might indicate an issue with the instance role itself or metadata service access.
- If using AWS SSO: Run
-
Validate Your System Clock
Ensure your system's time is accurate. On Linux,timedatectl statuscan show synchronization status. You might need to synchronize with NTP:
bash sudo ntpdate pool.ntp.org # On older systems sudo systemctl restart systemd-timesyncd # On systemd-based systems -
Review IAM Console
As a last resort, if all checks point to valid credentials but the issue persists, log into the AWS Management Console with your root account or another administrative user. Navigate to IAM, find the user or role corresponding to theAWS_ACCESS_KEY_IDyou're using, and verify:- The user/role exists and is active.
- The access keys you are using are active and not deactivated. You might need to generate new keys if the old ones are compromised or simply not working.
Code Examples
Here are some concise examples to help you troubleshoot and correctly configure your environment.
Listing AWS CLI Configuration
aws configure list
# Example output for a default profile:
# Name Value Type Location
# ---- ----- ---- --------
# profile <not set> None None
# access_key ****************ABCD shared-credentials-file
# secret_key ****************WXYZ shared-credentials-file
# region us-east-1 config-file ~/.aws/config
Checking Caller Identity
This command directly uses your current AWS configuration to verify credentials.
aws sts get-caller-identity
# Example success output:
# {
# "UserId": "AIDACKCEVSQ6CEXAMPLE:my-cli-session",
# "Account": "123456789012",
# "Arn": "arn:aws:iam::123456789012:user/my-cli-user"
# }
# If using an assumed role:
# {
# "UserId": "AROARWEXAMPLEM2R7X47:my-assumed-role-session",
# "Account": "123456789012",
# "Arn": "arn:aws:sts::123456789012:assumed-role/MyRole/my-assumed-role-session"
# }
Setting Environment Variables
This is a common way to temporarily override credentials, useful for testing or in CI/CD pipelines.
export AWS_ACCESS_KEY_ID="AKIAIOSFODNN7EXAMPLE"
export AWS_SECRET_ACCESS_KEY="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
export AWS_SESSION_TOKEN="IQoJb3JpZ2luX2VjEL..." # Only if using temporary credentials
export AWS_DEFAULT_REGION="us-west-2"
Python Boto3 Example
When using an AWS SDK like Boto3, the SDK automatically looks for credentials in a specific order (environment variables, ~/.aws/credentials, EC2 instance profiles).
import boto3
from botocore.exceptions import ClientError
try:
# This will use credentials configured via CLI, env vars, or instance profile
s3_client = boto3.client('s3', region_name='us-east-1')
response = s3_client.list_buckets()
print("Successfully listed buckets:")
for bucket in response['Buckets']:
print(f" {bucket['Name']}")
except ClientError as e:
if e.response['Error']['Code'] == 'InvalidClientTokenId':
print(f"ERROR: InvalidClientTokenId encountered. Your AWS credentials are invalid or expired.")
print(f"Details: {e}")
else:
print(f"An unexpected AWS error occurred: {e}")
except Exception as e:
print(f"An unexpected error occurred: {e}")
# You can also explicitly pass credentials, though generally not recommended
# s3_client = boto3.client(
# 's3',
# aws_access_key_id='YOUR_ACCESS_KEY',
# aws_secret_access_key='YOUR_SECRET_KEY',
# aws_session_token='YOUR_SESSION_TOKEN', # Optional for temporary credentials
# region_name='us-east-1'
# )
Environment-Specific Notes
The context in which you encounter InvalidClientTokenId can significantly influence the troubleshooting steps.
Local Development
On your local machine, the AWS CLI and SDKs primarily source credentials from:
1. Environment Variables: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN, AWS_DEFAULT_REGION. These take highest precedence. Check your shell's profile (e.g., .bashrc, .zshrc) or current session.
2. ~/.aws/credentials file: This is where aws configure stores static credentials or profiles.
3. ~/.aws/config file: Used for region, output format, and profile definitions, including source_profile for chained credentials or sso_start_url for AWS SSO.
When troubleshooting locally, always check these sources in order. If you're using AWS SSO, ensure your SSO session hasn't expired (aws sso login).
Docker Containers
Running AWS commands within a Docker container adds another layer. Credentials can be passed in a few ways:
1. Environment Variables: The most common and often cleanest method.
bash
docker run -e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \
-e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \
-e AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN \
-e AWS_DEFAULT_REGION=$AWS_DEFAULT_REGION \
my_aws_cli_image aws s3 ls
2. Mounting ~/.aws volume: You can mount your host's .aws directory into the container.
bash
docker run -v ~/.aws:/root/.aws:ro my_aws_cli_image aws s3 ls --profile my-profile
Be cautious with this method, especially in production, as it can expose credentials. Ensure correct user permissions within the container for the mounted volume.
3. IAM Roles (for containers running on EC2/ECS/EKS): The most secure approach. The container inherits the IAM role attached to the underlying EC2 instance (for ECS EC2 launch type) or the task definition (for ECS Fargate, EKS pod roles). If InvalidClientTokenId appears here, it usually means:
* No IAM role is assigned to the task/pod/instance.
* The IAM role exists but is misconfigured or has been deleted.
* The container cannot reach the EC2 instance metadata service (IMDS) to retrieve temporary credentials, possibly due to network configuration or a proxy.
Cloud Environments (EC2, ECS, Lambda, EKS)
In cloud compute environments, the primary and recommended method for providing AWS credentials is via IAM Roles.
* EC2 Instances: An instance profile with an IAM role is attached to the EC2 instance. The AWS SDKs and CLI automatically retrieve temporary credentials from the instance metadata service (IMDS). If you see InvalidClientTokenId on EC2, check that an instance role is attached and has not been removed or misconfigured.
* AWS Lambda Functions: Each Lambda function is assigned an execution role. This error would be highly unusual directly from Lambda's execution, as the service manages the role's credentials. If it occurs, it points to a misconfiguration of the Lambda function's IAM role itself, or code within the Lambda is attempting to use hardcoded or external credentials that are failing, rather than its execution role.
* ECS Tasks / EKS Pods: These also leverage IAM roles, either via task execution roles for ECS or IAM Roles for Service Accounts (IRSA) for EKS. Similar to EC2, verify the correct role is associated and accessible. For EKS, ensure the IRSA configuration (Service Account, annotation, OIDC provider) is correct.
Frequently Asked Questions
Q: Is InvalidClientTokenId a permissions error?
A: No, it is an authentication error, not a permissions (authorization) error. It means AWS couldn't verify who you are, regardless of what permissions you might have. A permissions error would typically be AccessDeniedException.
Q: How can I tell if my AWS credentials are temporary?
A: Temporary credentials always include an AWS_SESSION_TOKEN in addition to the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY. If you see this token in your environment variables or ~/.aws/credentials file, your credentials are temporary and will expire.
Q: Can a firewall or proxy cause this error?
A: Indirectly. If a firewall or proxy prevents your application or CLI from reaching the AWS Security Token Service (STS) endpoint (e.g., sts.amazonaws.com or a region-specific STS endpoint) to obtain or refresh temporary credentials, then subsequent attempts to use expired tokens would result in InvalidClientTokenId. However, the error itself isn't a direct network connectivity problem to the target service but an authentication failure.
Q: What's the best way to prevent this error?
A: For applications and services running on AWS (EC2, ECS, Lambda, EKS), always use IAM roles for credentials. This eliminates managing keys manually and handles credential rotation automatically. For human users, leverage AWS SSO (Single Sign-On) for managed temporary credentials. Avoid storing static AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY directly in code or long-lived environment variables.
Q: Does Multi-Factor Authentication (MFA) play a role here?
A: MFA is typically required to obtain temporary credentials (e.g., when logging in via SSO or using aws sts get-session-token). If you fail the MFA step, you won't get the credentials in the first place. Once you have the temporary credentials, the InvalidClientTokenId error would mean those obtained credentials have expired or are malformed, not that MFA itself is failing.
Related Errors
(None)