| Package | aws-cli/2.37.3 |
|---|---|
| AWS Region | ap-south-1 is used for examples where a Region is required. Credential selection itself is not tied to this example Region |
| Lab environment | Workstation with AWS CLI v2 and configured credentials — AWS CLI tutorial Install AWS CLI on Ubuntu · Install AWS CLI on Debian |
| Privilege | Permission to read local ~/.aws/ files and environment variables in the shell where aws runs |
| Scope | How to see which credential source the AWS CLI selected (environment variables, named profile, shared files, assume role, aws login, or IAM Identity Center), how to read the TYPE and LOCATION columns from aws configure list, and how to confirm the resulting account or role with aws sts get-caller-identity. Does not cover missing credentials — see Fix AWS CLI Unable to locate credentials — or API authorization failures after authentication succeeds. |
| Related guides | AWS CLI Tutorial Fix AWS CLI Unable to locate credentials Fix AWS CLI ExpiredToken Fix AWS CLI InvalidClientTokenId AWS Tutorial |
When an AWS CLI command runs with the wrong AWS account, IAM user, or role, start with aws configure list. The TYPE column on the access_key and secret_key rows shows where the CLI obtained the credentials — for example env, shared-credentials-file, or assume-role. Run aws sts get-caller-identity next to confirm the AWS account and IAM user or role those credentials represent.
Several settings can influence which AWS identity the CLI ultimately uses. --profile and AWS_PROFILE select a profile, while environment credentials, static keys, role assumption, IAM Identity Center, aws login, container credentials, or EC2 instance metadata can supply the credentials used to sign the request.
The examples use AWS CLI v2, but the troubleshooting method is the same on any host: identify where the CLI obtained its credentials, then verify the resulting AWS account and principal.
In AWS CLI terms, credentials are the values used to sign an AWS API request: an access key ID and secret access key, plus a session token when temporary credentials are being used.
Quick answer
Run these two commands in the same terminal or process environment where the wrong AWS identity appeared:
aws configure listconfigure list answers where the credentials came from — read TYPE and LOCATION on the access_key and secret_key rows.
aws sts get-caller-identityget-caller-identity answers who the CLI authenticated as — read Account and Arn.
If the profile looks right but the identity is still wrong, check the AWS credential and profile environment variables in Check environment variable overrides below.
| Goal | Command | What to read |
|---|---|---|
| See provider per field | aws configure list |
TYPE and LOCATION on access_key / secret_key rows |
| List profile names | aws configure list-profiles |
Names defined in the active config and credentials files |
| Confirm account or role | aws sts get-caller-identity |
Account and Arn after credentials resolve |
| Trace provider order | aws --debug sts get-caller-identity 2>&1 |
Looking for credentials via: lines (redact secrets before sharing) |
How AWS CLI chooses credentials
An AWS CLI profile is a named set of configuration values, such as credentials, Region settings, or instructions for obtaining temporary credentials.
Before troubleshooting, separate two questions: which profile did the CLI select, and where did it actually get the credentials?
AWS_PROFILE and --profile both select a profile, but they are not identical during credential resolution. If AWS_PROFILE is set alongside AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, the environment credentials normally take precedence. When you explicitly pass --profile NAME, the AWS CLI uses that profile's credential providers instead of the normal environment credential provider.
A profile can still deliberately use environment credentials as its source — for example with credential_source = Environment in an assume-role profile.
aws command
|
v
How was the profile chosen?
|
+--------------+--------------+
| |
--profile NAME AWS_PROFILE=NAME
explicit profile environment setting
| |
| +--> AWS_ACCESS_KEY_ID /
| AWS_SECRET_ACCESS_KEY
| can take precedence
v
resolve credentials
from selected profile
|
+--> static credentials
+--> assume role
+--> IAM Identity Center
+--> aws login
+--> credential_process
+--> credential_source
|
v
resolved credentials
|
+---------+---------+
| |
v v
aws configure list sts get-caller-identity
WHERE from? WHO am I?AWS documents the following overall precedence order for CLI configuration and credentials. Do not read this as meaning that access keys can be supplied at every level — for example, --profile is a command-line option, but there is no normal --access-key-id option.
| Higher → lower | Credential or config source |
|---|---|
| 1 | Command-line options such as --profile for applicable settings |
| 2 | Environment variables |
| 3 | Assume role |
| 4 | Assume role with web identity |
| 5 | IAM Identity Center |
| 6 | Shared credentials file |
| 7 | External or custom process (credential_process) |
| 8 | Config file |
| 9 | Container credentials |
| 10 | EC2 instance profile |
When TYPE is env and you selected the profile with AWS_PROFILE, file-based profile keys on disk are not what signed the call — even if AWS_PROFILE points at the expected profile name.
Check credential source with aws configure list
aws configure list is the fastest way to see which values the next aws command will use. Run it in the failing shell before editing ~/.aws/ files.
aws configure listWith a named profile backed by static keys in the shared credentials file:
NAME : VALUE : TYPE : LOCATION
profile : glc-credtrace-lab-file : env : ['AWS_PROFILE']
access_key : ****************JKVY : shared-credentials-file :
secret_key : ****************Hl2A : shared-credentials-file :
region : ap-south-1 : env : ['AWS_REGION', 'AWS_DEFAULT_REGION']TYPE tells you the kind of source that supplied the value. LOCATION tells you where that setting was selected or loaded from.
For credentials, LOCATION may be blank even when TYPE clearly identifies the provider:
TYPE |
Meaning |
|---|---|
env |
Credentials came from environment variables |
shared-credentials-file |
Credentials came from ~/.aws/credentials (or AWS_SHARED_CREDENTIALS_FILE) |
assume-role |
The CLI is using temporary credentials for an assumed IAM role |
login |
Credentials came from an aws login session |
sso |
Credentials came from IAM Identity Center (SSO) |
iam-role |
Credentials came from an EC2 instance profile through IMDS |
Read the table in this order:
profile— which named profile is active, and whether it came fromAWS_PROFILEor--profileaccess_key/secret_key— which provider supplied signing materialregion— often from environment variables or the config file, independent of who signed the request
Check which AWS profile is selected
AWS CLI profiles commonly store access keys in ~/.aws/credentials and other profile settings — such as Region, role, and IAM Identity Center configuration — in ~/.aws/config. The AWS CLI can read credentials from other supported locations too, so do not assume that finding keys in one of these files means they are the credentials currently in use.
Three inputs select the profile:
--profileon the command line — highest priority for profile selectionAWS_PROFILE— documented profile-selection variable for the AWS CLI- the implicit
defaultprofile when neither is set
You may also encounter AWS_DEFAULT_PROFILE in botocore-based environments, but for AWS CLI troubleshooting, start with AWS_PROFILE and --profile.
List profile names visible to the CLI:
aws configure list-profilesglc-credtrace-lab-file
glc-credtrace-lab-roleWhen AWS_PROFILE selects one profile but the command passes another, --profile wins. The profile row shows manual and LOCATION shows --profile:
export AWS_PROFILE=glc-credtrace-lab-role
aws configure list --profile glc-credtrace-lab-fileNAME : VALUE : TYPE : LOCATION
profile : glc-credtrace-lab-file : manual : --profile
access_key : ****************JKVY : shared-credentials-file :
secret_key : ****************Hl2A : shared-credentials-file :
region : ap-south-1 : env : ['AWS_REGION', 'AWS_DEFAULT_REGION']Because --profile glc-credtrace-lab-file is explicitly supplied, the next command resolves credentials through that profile rather than the profile named by AWS_PROFILE:
aws sts get-caller-identity --profile glc-credtrace-lab-file{
"UserId": "AIDAU7QAIUYJEXAMPLE",
"Account": "123456789012",
"Arn": "arn:aws:iam::123456789012:user/glc-credtrace-lab-user"
}Custom file paths and $HOME change which profiles exist and which files are read:
| Variable or path | Effect |
|---|---|
AWS_SHARED_CREDENTIALS_FILE |
Replaces ~/.aws/credentials |
AWS_CONFIG_FILE |
Replaces ~/.aws/config |
$HOME |
Default base for ~/.aws/ when custom paths are not set |
Check all three when an expected profile is missing:
printf 'HOME=%s\n' "$HOME"
printf 'AWS_CONFIG_FILE=%s\n' "${AWS_CONFIG_FILE:-<default>}"
printf 'AWS_SHARED_CREDENTIALS_FILE=%s\n' "${AWS_SHARED_CREDENTIALS_FILE:-<default>}"HOME=/home/labuser
AWS_CONFIG_FILE=<default>
AWS_SHARED_CREDENTIALS_FILE=<default>If configure list-profiles omits an expected name, verify $HOME and the custom path variables before recreating profiles.
Assume-role profiles
A profile can chain to a role with role_arn and source_profile in ~/.aws/config:
[profile glc-credtrace-lab-role]
region = ap-south-1
role_arn = arn:aws:iam::123456789012:role/glc-credtrace-lab-role
source_profile = glc-credtrace-lab-filesource_profile is not the only way an assume-role profile can obtain its starting credentials. A profile can instead name a credential_source — for example Ec2InstanceMetadata, EcsContainer, or Environment:
[profile app-role]
role_arn = arn:aws:iam::123456789012:role/AppRole
credential_source = Ec2InstanceMetadata EC2 instance role credentials
|
v
credential_source
|
v
sts:AssumeRole
|
v
temporary credentials for the target roleNow select the role profile and see where its credentials come from:
export AWS_PROFILE=glc-credtrace-lab-role
aws configure listNAME : VALUE : TYPE : LOCATION
profile : glc-credtrace-lab-role : env : ['AWS_PROFILE']
access_key : ****************N6MX : assume-role :
secret_key : ****************8mY8 : assume-role :
region : ap-south-1 : env : ['AWS_REGION', 'AWS_DEFAULT_REGION']assume-role in the TYPE column means AWS Security Token Service (STS) issued temporary credentials for the role in role_arn. The credentials resolved from source_profile (or credential_source) are used to obtain the role session through sts:AssumeRole. The resulting temporary role credentials are then used to sign subsequent AWS service requests.
Assume-role credentials are cached under ~/.aws/cli/cache and reused across CLI commands until they expire. When debug output shows Credentials for role retrieved from cache, the AWS CLI found previously obtained temporary role credentials in its local cache instead of calling STS again.
IAM Identity Center and aws login
aws sso login authenticates an IAM Identity Center profile. aws login is different from IAM Identity Center — it uses your AWS Management Console sign-in through a browser-based flow and gives the CLI temporary credentials that it manages automatically. Do not treat them as interchangeable.
When no profile is selected and aws login supplied the session, configure list can show login as the provider:
aws configure listOn a host with an active aws login session:
NAME : VALUE : TYPE : LOCATION
profile : <not set> : None : None
access_key : ****************HRE7 : login :
secret_key : ****************Dy/l : login :
region : ap-south-1 : config-file : ~/.aws/configFor IAM Identity Center profiles, refresh with aws sso login --profile <name> when the SSO cache expires. For aws login, static credentials that remain in the target profile can take precedence over login credentials — use aws configure list to see which provider won. See Fix AWS CLI ExpiredToken when STS reports an expired session.
Check environment variable overrides
AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY override keys loaded from a profile selected with AWS_PROFILE. AWS documents environment credential variables as higher precedence than credentials stored in profiles selected that way. Explicit --profile behaves differently — see How AWS CLI chooses credentials.
AWS_PROFILE is set but TYPE is env
Export a profile name and separate environment keys to reproduce the override:
export AWS_PROFILE=glc-credtrace-lab-file
export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
aws configure listNAME : VALUE : TYPE : LOCATION
profile : glc-credtrace-lab-file : env : ['AWS_PROFILE']
access_key : ****************MPLE : env :
secret_key : ****************EKEY : env :
region : ap-south-1 : env : ['AWS_REGION', 'AWS_DEFAULT_REGION']The selected profile is glc-credtrace-lab-file, but the credentials did not come from that profile. TYPE=env means AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are supplying the actual signing credentials.
Unset the environment keys and verify the profile identity:
unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN
aws configure listThe access_key row should now show shared-credentials-file. Confirm with STS:
aws sts get-caller-identityNon-secret and secret variables
Check which AWS environment variables are set in the current shell. First, check the settings that are safe and useful to see in full:
env | grep -E '^AWS_(PROFILE|DEFAULT_PROFILE|CONFIG_FILE|SHARED_CREDENTIALS_FILE|REGION|DEFAULT_REGION)='AWS_PROFILE=glc-credtrace-lab-role
AWS_REGION=ap-south-1
AWS_DEFAULT_REGION=ap-south-1Redact credential values separately:
env | grep -E '^AWS_(ACCESS_KEY_ID|SECRET_ACCESS_KEY|SESSION_TOKEN)=' \
| sed 's/=.*/=***/'AWS_ACCESS_KEY_ID=***
AWS_SECRET_ACCESS_KEY=***AWS STS temporary credentials normally include three values: an access key ID, secret access key, and session token. Temporary access key IDs commonly begin with ASIA. If you export temporary credentials manually, make sure you export AWS_SESSION_TOKEN as well. A missing token with env-based keys produces Partial credentials found instead of a clean override.
On EC2, unset explicit AWS_* credential variables when the instance profile should win through IMDS.
Confirm the final AWS identity with STS
get-caller-identity is useful because you do not need to know which IAM policy granted access before using it to identify the caller. Its purpose here is simply to answer: which AWS identity do these resolved credentials represent?
After configure list shows the provider, confirm the AWS account and principal:
export AWS_PROFILE=glc-credtrace-lab-file
aws sts get-caller-identity{
"UserId": "AIDAU7QAIUYJEXAMPLE",
"Account": "123456789012",
"Arn": "arn:aws:iam::123456789012:user/glc-credtrace-lab-user"
}For the assume-role profile:
export AWS_PROFILE=glc-credtrace-lab-role
aws sts get-caller-identity{
"UserId": "AROAU7QAIUYJEXAMPLE:botocore-session-1790561409",
"Account": "123456789012",
"Arn": "arn:aws:sts::123456789012:assumed-role/glc-credtrace-lab-role/botocore-session-1790561409"
}Compare Account and Arn to the account and role the job is supposed to use. get-caller-identity does not print the credential source — pair it with the TYPE column from configure list.
Arn pattern |
Meaning |
|---|---|
arn:aws:iam::…:user/… |
IAM user access keys |
arn:aws:sts::…:assumed-role/… |
Temporary role session |
arn:aws:iam::…:root |
Account root user (common with aws login on a root session) |
If the ARN is correct but API calls still fail with AccessDenied, authentication succeeded and authorization failed — see AccessDenied despite AdministratorAccess.
Trace difficult cases with --debug
If aws configure list still does not explain where the credentials came from, enable debug logging and look only at the credential-provider messages. AWS CLI v2 uses Botocore internally for credential resolution, so credential-related debug lines often contain botocore.credentials. Run debug only on trusted machines and redact secrets before sharing logs.
aws --debug sts get-caller-identity 2>&1 \
| grep -Ei 'Looking for credentials|Found credentials|assume-role|shared-credentials|login|sso|custom-process'For a role profile, trimmed output can look like this:
Looking for credentials via: env
Looking for credentials via: assume-role
Looking for credentials via: assume-role-with-web-identity
Looking for credentials via: sso
Looking for credentials via: shared-credentials-file
Found credentials in shared credentials file: ~/.aws/credentials
Credentials for role retrieved from cache.
Retrieved credentials will expire at: 2026-09-28 03:10:10+00:00Do not stop at the first Found credentials line when troubleshooting an assume-role profile. Those credentials can be the source credentials used to obtain the role session. Confirm the final principal with aws sts get-caller-identity.
Looking for credentials via: envruns first — empty env vars are skipped quicklyFound credentials in shared credentials fileoften points atsource_profilekeys before assume-role runsCredentials for role retrieved from cachemeans cached role credentials under~/.aws/cli/cachewere reusedLooking for credentials via: custom-processindicates acredential_processexternal command
Debug output can include Authorization headers, session tokens, and access keys. Pipe through sed to redact values, or grep for provider lines only. Never paste raw --debug output into tickets or documentation.
Troubleshoot AWS CLI using the wrong credentials
In most cases, the TYPE value immediately points to the source you need to investigate.
| Symptom | What it means | What to check |
|---|---|---|
AWS_PROFILE is correct but TYPE is env |
Credential environment variables are overriding credentials from that profile | AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_SESSION_TOKEN |
--profile NAME still gives an unexpected identity |
The selected profile itself may contain role, SSO, login, or custom-process configuration | aws configure list --profile NAME, profile configuration, then aws sts get-caller-identity --profile NAME |
| Wrong profile selected | A different profile name is active | profile row and LOCATION; pass --profile NAME explicitly or correct AWS_PROFILE |
Expected login, but TYPE is shared-credentials-file |
Static credentials remain in that profile | Remove or move conflicting static credentials if the profile should use aws login |
| Expected IAM Identity Center but wrong provider | Wrong profile, stale env vars, or different credential source | aws configure list --profile NAME, credential env vars, then aws sso login --profile NAME |
configure list shows <not set> for keys |
No provider succeeded | Configure a profile or env keys — Unable to locate credentials |
Profile exists in file but not in list-profiles |
Wrong $HOME or custom file paths |
AWS_CONFIG_FILE, AWS_SHARED_CREDENTIALS_FILE, and $HOME |
| Role profile fails assume | Trust or caller permissions | IAM trust on the role and sts:AssumeRole on the source identity |
ExpiredToken or InvalidClientTokenId |
Stale temporary credentials | Refresh assume-role, SSO, or aws login — ExpiredToken or InvalidClientTokenId |
get-caller-identity works, API calls fail |
Authorization, not credential source | AccessDenied — see AccessDenied despite AdministratorAccess |
AWS CLI works as one user but shows different credentials with sudo
AWS credential files are normally relative to the current user's home directory. Running the CLI through sudo, another service account, a container, CI runner, or IDE may read a completely different ~/.aws directory.
whoami
echo "$HOME"
aws configure listlabuser
/home/labuser
NAME : VALUE : TYPE : LOCATION
profile : glc-credtrace-lab-file : env : ['AWS_PROFILE']
access_key : ****************JKVY : shared-credentials-file :Compare with root's environment:
sudo sh -c 'whoami; echo "$HOME"; aws configure list'root
/root
NAME : VALUE : TYPE : LOCATION
profile : <not set> : None : None
access_key : <not set> : None : NoneRun the AWS CLI as the user whose credentials are configured. If another service account genuinely needs AWS access, configure an appropriate authentication method for that account instead of broadly sharing a user's ~/.aws/credentials file. For controlled automation, custom credential and config paths can also be set with AWS_SHARED_CREDENTIALS_FILE and AWS_CONFIG_FILE, provided file permissions remain appropriately restricted.
Summary
Use aws configure list to identify where the AWS CLI resolved its active credentials, then use aws sts get-caller-identity to verify the resulting account and principal. If AWS_PROFILE points to the expected profile but TYPE says env, the CLI is using credentials from AWS_ACCESS_KEY_ID and related environment variables instead of credentials stored in that profile. For harder cases, inspect custom credential paths, $HOME, role chains, or filtered --debug provider lines.
References
- Authentication and access credentials for the AWS CLI — configuration and credential precedence
- AWS CLI Configuration and credential file settings
- AWS CLI Environment variables
- AWS CLI
configure listcommand - Using an IAM role in the AWS CLI —
source_profile,credential_source, and assume-role caching - AWS STS GetCallerIdentity
- AWS CLI
aws logincommand
Frequently Asked Questions
Does get-caller-identity show the credential source?
No. It returns the authenticated principal (Account, Arn, UserId) only. Use aws configure list for the provider (TYPE / LOCATION) and optional aws --debug grep for the resolver order.
Why is my profile ignored?
Usually the profile name is selected correctly, but another credential source supplied the signing keys. If you selected the profile with AWS_PROFILE, environment credentials can still take precedence — check whether TYPE is env. If you explicitly used --profile NAME, check the credential configuration inside that profile, such as role_arn, IAM Identity Center, credential_process, or credential_source. Custom AWS_CONFIG_FILE paths and role profiles that return assumed-role credentials are other common causes.
Why does aws configure list show profile as not set?
That does not necessarily mean the AWS CLI has no credentials. It usually means no named profile was explicitly selected, so the CLI is using its default configuration context. Check the access_key and secret_key rows to see whether credentials were still resolved — for example through aws login, environment variables, or the default profile.
Why does AWS CLI use environment credentials even when AWS_PROFILE is set?
AWS_PROFILE selects a profile, but AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_SESSION_TOKEN have higher precedence than credentials stored in that profile. Check the access_key and secret_key rows in aws configure list; if TYPE is env, the environment variables are supplying the credentials. Explicit --profile disables the normal environment credential provider unless the profile itself is configured to use environment credentials.
What is credential_process?
credential_process lets an external command return credentials to the AWS CLI. In --debug output, this provider typically appears as custom-process. The external program must return the credential JSON format expected by the AWS CLI, including AccessKeyId, SecretAccessKey, and optionally SessionToken and Expiration. Unlike assume-role credentials, the AWS CLI does not cache credentials returned by credential_process; the external program must implement caching if it needs it.

