Skip to main content
DevOps Insightsguides & answers

AWS CLI · troubleshooting

Unable to locate credentials

The AWS CLI or SDK found no credentials anywhere it looks: no environment variables, no profile with keys, no instance or container role. Run aws configure list to see what it found, then fix that source, often a missing profile, sudo or a container that cannot reach the instance role.

Reproduced on aws-cli 2.32.5, . Where the text says “reproduced”, the behaviour was run on that version, not taken from documentation.

First published

New to this? Read what is actually happening first, then come back to the steps.

On this page · 10 sections

Before you start

  • A shell where the command fails, as the same user and in the same container.
  • The AWS CLI, for aws configure list (it reads local settings only, no AWS call).

Run this first

step 1 of 2
aws configure list

Look for <not set> for access_key, and which profile was picked

Shows the profile, keys and region in use and the location each came from, without calling AWS.

Work out which cause you have

A few questions to narrow the list. Every answer ends in a command that confirms or rules the cause out — this cannot see your cluster, so nothing here is a certainty until you have checked.

Narrow it down

0 answered · nothing is sent anywhere

Where does it fail?

Cause space

3 of 3 still possible

  • Nothing is configured for this user or profileCommon
  • The command runs as another user or with a cleaned environmentCommon
  • A container on EC2 cannot reach the instance roleCommon

Nothing ruled out yet. Answer the question above and the branches your answer eliminates will strike through here.

Check it with a tool

Or diagnose it manually

In this order. The first command usually contains the whole answer.

  1. Step 1

    aws configure list

    Shows the profile, keys and region in use and the location each came from, without calling AWS.

    Look for <not set> for access_key, and which profile was picked

  2. Step 2

    env | grep '^AWS_' | sed 's/=.*/=…/'

    Lists which AWS variables are set in this environment, without printing their values.

    Look for AWS_PROFILE, AWS_ACCESS_KEY_ID or AWS_CONFIG_FILE present or missing compared with where it works

Every cause, and how to fix it

Ordered by how often each one turns out to be the answer.

Nothing is configured for this user or profile

Common

No keys in the environment, and the profile in use (default, or the one named by --profile or AWS_PROFILE) has no keys, no SSO settings and no role to assume.

Confirm

aws configure list
aws configure list --profile NAME

access_key <not set>, and a profile and LOCATION you did not expect

Fix

  • Configure the profile you mean: aws configure sso for IAM Identity Center, or aws configure for access keys on a personal machine.
  • Select it explicitly with --profile NAME or AWS_PROFILE=NAME, and check the spelling: a misspelled name gives The config profile (NAME) could not be found.
aws configure list

Shows each value and where it came from; it reads local settings and makes no AWS call.

The command runs as another user or with a cleaned environment

Common

sudo, cron, systemd services and CI jobs run with a different HOME or without your environment variables, so they look in another ~/.aws and find nothing.

Confirm

whoami; echo "HOME=$HOME AWS_PROFILE=${AWS_PROFILE:-unset}"
sudo aws configure list

A different user or HOME, and <not set> where your own shell has values

Fix

  • Run the AWS command as your own user rather than under sudo, or point it at the right files with AWS_CONFIG_FILE and AWS_SHARED_CREDENTIALS_FILE.
  • For services and cron, give the machine a role (an EC2 instance profile) instead of copying personal keys.
  • In CI, provide credentials the CI way: OIDC role assumption in GitHub Actions rather than stored keys.

A container on EC2 cannot reach the instance role

Common

The instance has a role, the host's CLI works, but a container on a bridge network fails: IMDSv2's default hop limit of 1 drops the token response before it reaches the container.

Confirm

aws ec2 describe-instances --instance-ids INSTANCE_ID --query 'Reservations[].Instances[].MetadataOptions'

HttpTokens required and HttpPutResponseHopLimit 1, while the same command works on the host

Fix

  • Raise the hop limit to 2 for that instance, if containers on it may use the instance role.
  • Better on ECS or EKS: give the workload its own role (ECS task role, EKS Pod Identity or IRSA), which does not depend on IMDS.
aws ec2 modify-instance-metadata-options --instance-id INSTANCE_ID --http-put-response-hop-limit 2 --http-endpoint enabled

Lets containers on the instance use its role. Prefer a per-workload role where the platform has one.

Understanding it properly

Skip this if you are mid-incident — the working part of the page is above. Worth reading afterwards, because understanding the mechanism is what stops the next one.

In plain terms

Before it can call AWS, the CLI or your program needs to prove who it is. It checks a fixed list of places in order: settings on the command line, environment variables, your ~/.aws files, and finally the role attached to the server or container it runs on. This error means every one of them came up empty. Nothing is wrong with your permissions yet; AWS was never asked.

Words used on this page

Credential chain
The fixed order in which the CLI and SDKs look for credentials: command line, environment variables, assume-role and web identity, IAM Identity Center, the credentials and config files, a credential process, container credentials, and the EC2 instance profile.
Profile
A named set of settings in ~/.aws/config and ~/.aws/credentials, chosen with --profile or AWS_PROFILE.
Instance profile
An IAM role attached to an EC2 instance, whose temporary credentials come from the instance metadata service (IMDS).
Hop limit
How many network hops an IMDSv2 token response may travel. The default of 1 stops at the instance, so a container behind a bridge network cannot get one.
What is actually happening

The message is botocore's NoCredentialsError, the library behind the AWS CLI and boto3. It is raised before any request is sent, so it is never an IAM permission problem; that would be AccessDenied.

The CLI checks, in order: command line options, environment variables, assume role, assume role with web identity, IAM Identity Center, the credentials file, a credential process, the config file, container credentials (ECS), and the EC2 instance profile. Only when all of them are empty does this error appear.

Reproduced on aws-cli 2.32.5 with an empty home directory: Unable to locate credentials. You can configure credentials by running "aws login", exit code 253. Older versions end the sentence with aws configure. A profile that exists but has no keys gives the same error; a misspelled profile name gives The config profile (NAME) could not be found instead.

An IAM Identity Center (SSO) profile that was never logged in fails differently: Error loading SSO Token: Token for NAME does not exist (reproduced on the same version). Run aws sso login --profile NAME for that one.

On EC2 with IMDSv2, the token response has a hop limit of 1 by default. A Docker container on a bridge network is one hop further away, so it cannot fetch the instance role's credentials, and the SDK inside it reports this error.

How to tell this is your problem
WhereWhat you see
aws CLIUnable to locate credentials. You can configure credentials by running "aws configure". (or "aws login" on newer versions)
Python (boto3)botocore.exceptions.NoCredentialsError: Unable to locate credentials
TimingWorks in your shell, fails under sudo, in cron, in a container or in CI

How to know it is actually fixed

  • aws sts get-caller-identity prints the account and the role or user you expected.
  • The same command works under the user, container or job that failed.

Stopping it happening again

  • Give machines and workloads roles (instance profiles, task roles, Pod Identity, OIDC in CI) instead of copying keys.
  • Name the profile explicitly in scripts with --profile, so they do not depend on whoever runs them.
  • When running containers on EC2 that need the instance role, set the hop limit when you launch the instance.

Security considerations

  • Do not fix this by pasting long-lived access keys into a Dockerfile, an image or a repository. On EC2, ECS, EKS or CI, use the role the platform provides.
  • Raising the IMDS hop limit lets every container on the instance use the instance's role. If containers should have their own permissions, give them their own role (ECS task role, EKS Pod Identity or IRSA) instead.
  • aws configure list prints only the last characters of the keys; still, do not paste its output into tickets without checking.

Sources

Behaviour described here is drawn from official documentation. Where a figure could not be confirmed on an official page it is attributed in the text rather than stated as canonical.

Did this get you to an answer?

No text box on purpose — please do not paste production logs anywhere

Something wrong or out of date? Report it