AWS CLI "Unable to Locate Credentials": Every Fix

Logeshwaran.C

"Unable to locate credentials. You can configure credentials by running "aws configure"." means the AWS CLI checked every place it knows to look — environment variables, the credentials file, the config file, and (on EC2, ECS or Lambda) the instance or task role — and found nothing usable in any of them. The fix is almost never just "run aws configure" again. Here's the counterintuitive part: running aws configure again can make things worse. If you're on an EC2 instance with a working IAM role attached, typing in a static access key overrides that role with a long-lived credential you now have to rotate and protect by hand — and if you paste the wrong one, you get this exact same error, just from a different cause.

⚡ Quick Answer

Diagnose first → run aws configure list to see exactly which credential source (or none) the CLI is using.

Nothing configured → run aws configure and paste an IAM user's access key ID and secret access key — never the AWS account root user's.

On EC2/ECS/Lambda → don't run aws configure at all; fix the attached IAM role instead.

Every other cause — wrong profile, stray environment variables, an expired SSO session, a broken assume-role chain — is covered below, in the order you should actually check them. Start with the one command that tells you which.

What this error actually means

Jake runs a small phone shop, and last month he lost half a Saturday to this exact line of red text while trying to back up his point-of-sale database to S3. "It just says 'unable to locate,'" he told Ethan. "Locate what? I typed my password in like four times."

Ethan pulled up a stool. "That's the problem right there — the CLI doesn't use a password. It's not one thing it's looking for, it's a list. Environment variables first, then two files on your hard drive, then whatever role is attached to the machine you're running on. It works down that list in order, and the second one of those slots is empty, it doesn't try the next one and warn you — it goes straight to that error, even if the very next slot down would have worked fine."

Every AWS SDK and the CLI share what's officially called the credential provider chain. In order, the AWS CLI checks: command-line options (--profile), environment variables (AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY), the shared credentials file (~/.aws/credentials), the shared config file (~/.aws/config), and — only if you're running inside AWS infrastructure — container credentials (ECS task roles) or EC2 instance metadata. Credentials from environment variables always win over the credentials file, and the credentials file always wins over the config file for the same setting, even if the config file has more recent or more correct information. That precedence order is the single most common reason someone "fixes" their credentials and still sees this error five minutes later — they edited the file the CLI wasn't reading.

🙋‍♂️ Jake's Reality Check

"So there's no single place my credentials 'live'? I could have five different sets scattered around and never know which one is actually running?"

Yes, and that's normal, not a mistake. Most people have at least two — a credentials file for daily work and an environment variable set temporarily for one script. The trick isn't having only one; it's knowing which one wins.

Step 1: find out which source (or none) the CLI is using

Before you touch any file, run this one command. It costs nothing, needs no permissions, and tells you exactly where the CLI is currently looking.

  1. Open a terminal — Command Prompt, PowerShell, or Terminal on Mac/Linux, it works identically everywhere — and run aws configure list.
  2. Read the Type and Location columns, not just the values. env means an environment variable is in play; config_file means the credentials or config file; iam-role means an EC2 instance profile or ECS task role.
  3. If every row says <not set> with a Type of None, nothing is configured anywhere the CLI can see — skip to the section on setting credentials for the first time.
  4. If a row does show a source, run aws sts get-caller-identity next. This command needs zero IAM permissions to succeed and confirms whether the credentials the CLI found are actually valid, not just present.
What aws configure list shows Likely cause Jump to
Every row <not set> Never configured on this machine Setting credentials the first time
Type = config_file, but values still show <not set> Wrong file, wrong OS path, or wrong profile section File location and format
Type = env, values look wrong or old A stale environment variable is overriding your file Environment variable precedence
Type = iam-role, but commands still fail Role exists but the trust policy or network path is broken EC2 instance role troubleshooting
profile row shows a name you didn't set AWS_PROFILE is pointing at a profile that doesn't exist Profile mismatches

Cause 1: you've genuinely never configured credentials on this machine

If aws configure list shows nothing anywhere, this is the straightforward case, and it splits into two very different questions: where do you get credentials from, and how do you install them.

Where AWS credentials actually come from

An access key ID and secret access key belong to an IAM identity — either an IAM user or a role. You get them from the IAM console's Security credentials page for that user, sometimes called "my security credentials" when you're looking at your own account. You cannot recover a lost secret access key; AWS shows it to you exactly once, at creation time, and after that dialog box closes it's gone for good. If you lose it, the only path forward is deleting that key and creating a new one — there is no "resend" or "reveal" option, by design.

  1. Sign in to the IAM console as an administrator (not necessarily the root user — see the warning below) and open Users.
  2. Choose the IAM user that will run the CLI, then open its Security credentials tab.
  3. Under Access keys, choose Create access key, select a use case, and confirm.
  4. Copy or download both values immediately — the access key ID and the secret access key — because the secret is shown only this once.
  5. Run aws configure in your terminal and paste the access key ID, then the secret access key, then your default Region and output format when prompted.

⚠️ Never create access keys for the root user

AWS's own guidance is blunt about this: it strongly recommends against creating access key pairs for the account root user at all, since a root access key grants unrestricted, unrotatable-by-anyone-else access to the entire account. Root user keys are also a frequent target of automated credential-scanning attacks against public code repositories. Create an IAM user (or, better, use IAM Identity Center) and reserve the root login for the handful of tasks that genuinely require it.

Ethan is emphatic about this one. "I don't care how urgent the backup is," he told Jake. "You're not typing root keys into a config file that lives on a laptop that gets left in coffee shops. Make a user, give it exactly the S3 permissions it needs, and use that."

Cause 2: your credentials exist, but the CLI is looking in the wrong place

This is the single most common cause across Windows, Mac, and Linux alike: the credentials file exists, but not where the CLI expects to find it, or it's formatted in a way the CLI can't parse. The default location depends entirely on your operating system, and copying a credentials file between machines — or between a work laptop and a home one — is where most people trip.

Operating system Credentials file Config file
Windows %USERPROFILE%\.aws\credentials %USERPROFILE%\.aws\config
macOS ~/.aws/credentials ~/.aws/config
Linux ~/.aws/credentials ~/.aws/config

%USERPROFILE% on Windows and ~ on Mac and Linux both mean "your home folder" — the CLI resolves that automatically, so you never type out the literal C:\Users\yourname path unless you're troubleshooting. If you're moving a credentials file between machines, especially between a corporate-managed Windows profile and WSL (Windows Subsystem for Linux) running underneath it, remember those are two entirely separate home directories with two entirely separate .aws folders — a file sitting in your Windows home directory is invisible to the CLI running inside WSL, and vice versa. Copying it across manually, or symlinking one into the other, is the usual workaround, and it's worth doing deliberately rather than discovering the split by accident mid-error.

Format matters too. In the credentials file, a profile section looks like [default] or [work], with no profile prefix. In the config file, every profile except the default one needs the word profile in front of its name — [profile work], not [work]. Mixing that up is an easy typo, and the CLI won't warn you; it just won't find a section by that name, and you're back to "unable to locate credentials." If a profile has settings in both files, the credentials file's values for that profile take precedence over anything in the config file for the same profile.

✅ Why this is the one to use

Keep long-term access keys in the credentials file and everything else — Region, output format, role assumption, SSO settings — in the config file. That's the split AWS's own documentation recommends, it keeps the file that actually holds secrets smaller and easier to audit, and it's what most SDKs expect too.

You can also override both defaults entirely by setting the AWS_SHARED_CREDENTIALS_FILE and AWS_CONFIG_FILE environment variables to point somewhere else — useful for CI systems, but a classic trap if you set one of these once for a special project and forget it's still exported in every other terminal session afterward.

Cause 3: a named profile that doesn't exist, or doesn't match

If you use more than one AWS account — personal, work, a client's — you're probably using named profiles, either with --profile name on every command or by exporting AWS_PROFILE=name once per terminal session. Both point the CLI at a specific [profile name] section. If that section was renamed, deleted, or never existed — a common outcome of copy-pasting a teammate's setup instructions verbatim — the CLI won't fall back to your default profile. It fails outright with "unable to locate credentials," because as far as it's concerned, the profile you asked for has nothing in it.

Check which profile is active with aws configure list — the profile row shows it — and check what profiles actually exist by opening the credentials and config files directly, or running aws configure list-profiles. If AWS_PROFILE is set in your shell but doesn't match any section header, unset it (unset AWS_PROFILE on Mac/Linux, $env:AWS_PROFILE=$null in PowerShell) and the CLI will fall back to the [default] profile, if one exists.

Cause 4: leftover environment variables are silently winning

This is the one that makes people say "but I know my file is correct — I just checked it." The file can be perfect and still be ignored, because environment variables sit higher in the precedence order than either file. If you exported AWS_ACCESS_KEY_ID for a one-off script six months ago, in a shell profile that gets re-sourced every time you open a new terminal, that stale, possibly now-deleted key is still what the CLI reaches for first — before it even looks at your credentials file.

Precedence (highest wins) Source
1Environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
2The credentials file (~/.aws/credentials)
3The config file (~/.aws/config)
4Container credentials (ECS task role) or EC2 instance metadata

If AWS_PROFILE and the explicit key/secret environment variables are both set at once, the explicit key and secret win — the CLI uses those values directly rather than looking up the named profile at all. Find every AWS-related environment variable currently set with set | grep AWS_ on Mac/Linux or Get-ChildItem Env: | Where-Object Name -like "AWS_*" in PowerShell, and check your shell startup files (.zshrc, .bash_profile, PowerShell profile scripts) for old export AWS_... lines you forgot were there.

🙋‍♂️ Jake's Reality Check

"I set an environment variable for a client project ages ago and completely forgot. Is that dangerous, or just annoying?"

Both. Annoying because it's exactly this kind of confusing error. Dangerous because a stale access key sitting in a shell startup file is a credential nobody's actively watching — if it leaks, you won't notice until something's already gone wrong.

Cause 5: you're on EC2, and the instance role isn't reachable

Inside an EC2 instance, the CLI can pull temporary credentials automatically from the instance metadata service, provided an IAM role is attached — no aws configure needed, and none recommended. When this fails, it's almost always one of three things: no role is attached at all, the role's trust policy doesn't actually allow EC2 to assume it, or the metadata request is being blocked or timed out.

  1. Confirm a role is attached in the EC2 console under the instance's Security tab, or from inside the instance by querying the metadata service for the role name.
  2. Request temporary credentials for that role name from the metadata service directly. If the response is a set of credentials, the CLI should be able to use them too — the problem is elsewhere. If it isn't, read the error code in the response closely.
  3. Look specifically for AssumeRoleUnauthorizedAccess in that response. It means the role exists and is attached, but its trust policy doesn't grant ec2.amazonaws.com permission to assume it — an IAM console fix on the role's trust relationship, not anything you can change from the CLI.
  4. If the request times out entirely rather than returning any error, something in the network path — a restrictive security tool, a proxy, or table-ACL-style isolation on some managed platforms — is blocking access to the metadata service outright, and the CLI genuinely has nowhere left to look.

You can disable the CLI's attempt to reach EC2 metadata entirely with the AWS_EC2_METADATA_DISABLED environment variable — useful for forcing a fallback to another source when you know the metadata path is broken and don't want every command to hang waiting on it.

Cause 6: running inside ECS, Lambda, or a plain Docker container

Containers add one more link to the chain. An Amazon ECS task definition can have its own IAM task role, and when that's set correctly, credentials are delivered automatically through an environment variable the ECS agent injects at container start — AWS_CONTAINER_CREDENTIALS_RELATIVE_URI. If that variable isn't present inside the container, the CLI has no way to reach the task role, and you're back to this error even though the role itself is configured correctly in the task definition. Lambda functions work on the same principle: the execution role attached to the function supplies credentials to the runtime environment automatically, so a Lambda function that shows this error almost always has a misconfigured or missing execution role rather than a code problem.

A plain Docker container you're running yourself — not on ECS — has no concept of an instance role at all, because it isn't AWS infrastructure the CLI recognizes. For a bare container, you have three practical options: pass the access key and secret as environment variables at docker run time, mount your host's ~/.aws folder into the container as a read-only volume, or, for anything running on ECS specifically, define and attach a proper task role so the container never needs static keys baked into it at all. The task-role route is the one to prefer in production — it avoids long-lived credentials sitting inside an image or a running container's environment, where a leaked image layer or a misconfigured logging setup can expose them.

Cause 7: an assume-role profile that can't obtain credentials

If your profile is set up to assume a role — a role_arn plus a source_profile or credential_source in the config file — the CLI has to succeed at two separate steps: first, get valid base credentials from the source, then use those to call AssumeRole for the target role. A failure at either step surfaces as the same generic message. It's the source profile people forget to check — if the underlying IAM user's own credentials have expired, been deactivated, or simply never existed, the assume-role step never gets a chance to run, and the CLI reports it as "unable to locate credentials" rather than anything that points specifically at the role.

Run aws sts get-caller-identity --profile your-source-profile on the source profile by itself, with no role assumption involved, to isolate which half is broken. If that succeeds but the profile that assumes the role still fails, the problem sits in the trust policy on the target role — check that its trust relationship explicitly allows the source identity's ARN, and that any external ID or multi-factor authentication condition your team requires is actually being satisfied when you assume it.

🕐 What changed between versions

  • Before: AWS CLI version 1 handled credentials, assume-role, and SSO the same way for years with only incremental updates.
  • Now: version 1 entered maintenance mode on July 15, 2026 and reaches end-of-support on July 15, 2027 — new features, including credential-chain fixes, land in version 2 only.
  • What that means for you: if aws --version reports a 1.x build and you're chasing a credentials bug, upgrading to version 2 first is worth doing before you dig further, since the fix you need may already be there.

Cause 8: your IAM Identity Center (SSO) session expired

If your organization uses IAM Identity Center rather than long-term access keys, your profile stores an SSO start URL and role name, not a static key. Those sessions are temporary by design and expire on a schedule your administrators set — commonly somewhere between a few hours and a day. When the session lapses, the CLI can no longer refresh credentials silently, and running any command against that profile produces the same "unable to locate credentials" text, which is genuinely confusing the first time it happens, because nothing about your configuration actually changed.

The fix is simply aws sso login --profile your-profile, which reopens a browser window to reauthenticate. As of AWS CLI version 2.22.0, aws sso login and aws configure sso both default to the OAuth 2.0 authorization-code flow with PKCE rather than the older device-code flow — functionally the same result for you, just a different browser-based prompt than older screenshots and tutorials show. If you're on a machine without a way to open that browser window directly, look for a --use-device-code option, which the CLI itself will suggest when it detects it can't launch a browser locally.

Why this shows up so often on S3 commands specifically

There's nothing special about aws s3 commands and this error — S3 just happens to be the first service most people try, because it's the one they came to the CLI for in the first place, so it's the command where the credential chain gets tested for the very first time. The fix is identical to every cause above. One S3-specific wrinkle worth knowing: an instance profile can be attached to your EC2 instance and still fail specifically for S3 calls if the role's permissions policy — separate from its trust policy — doesn't grant the S3 actions you're calling. That's a different error in principle, an access-denied response rather than a missing-credentials one, but because both can appear during the same troubleshooting session, it's worth running aws sts get-caller-identity first to confirm credentials are present at all, before you start second-guessing the S3 permissions themselves.

🙋‍♂️ Jake's Reality Check

"So if I get 'access denied' instead of 'unable to locate credentials,' that's actually good news?"

In a sense, yes. "Access denied" means the CLI found valid credentials and AWS recognized them — it's a permissions problem on the IAM policy attached to that identity, which is a narrower, easier fix than "nothing was found at all."

Setting up credentials the right way, from a clean start

If you're starting completely fresh and want to avoid rebuilding this same troubleshooting session in six months, the durable version of "how do I get AWS credentials" is: create an IAM user with only the permissions it actually needs, or better, enroll in IAM Identity Center if your organization offers it, so you're never storing a long-lived secret on your laptop at all. For most individual developers and small setups, an IAM user with a scoped-down permissions policy — attached directly or through a group — is the practical middle ground: create the user, generate an access key from its Security credentials tab, and store that key only in the credentials file, never in a script, a repository, or a chat message. If your team is deciding how to structure who can create and manage those IAM users and their permissions in the first place, that's the broader IAM question worth reading up on separately, not something this specific error dictates for you.

Third-party credential managers, and when not to bother

A handful of open-source tools exist specifically to keep AWS credentials out of a plaintext file on disk entirely — they store the secret in your operating system's credential vault (macOS Keychain, Windows Credential Manager, or a Linux secret service) and hand the CLI temporary, short-lived credentials through environment variables only for the duration of a single command. If you juggle several AWS accounts daily and worry about a laptop-theft scenario, that's a real security improvement over a plaintext credentials file sitting in your home folder.

They're also, honestly, one more moving part to troubleshoot. If you're already fighting "unable to locate credentials," adding a wrapper tool that itself has its own credential-resolution logic on top of the CLI's isn't the moment to introduce it — get the plain credential chain working first, using the causes above, and only then decide whether a vault-backed wrapper is worth the extra layer for your day-to-day setup. For a single personal account with one profile, it usually isn't; for someone assuming a dozen client roles a day, it usually is.

The adjacent problem: static keys in CI/CD pipelines

Once your own machine is sorted, the next place this error tends to reappear is a CI/CD pipeline — a GitHub Actions workflow, most commonly — where someone pasted a static access key into a repository secret months ago, and it's since been rotated, deleted, or simply expired on the IAM side without anyone updating the pipeline to match. The AWS-recommended pattern for GitHub Actions specifically avoids this problem at the root: configure an OpenID Connect (OIDC) identity provider in IAM that trusts GitHub's token issuer, then set up an IAM role with a trust policy scoped to your specific repository. The workflow exchanges a short-lived, GitHub-signed token for temporary AWS credentials at run time using the official aws-actions/configure-aws-credentials action — no access key is ever stored as a GitHub secret, and there's nothing long-lived to expire, leak, or forget to rotate. It's more setup the first time than pasting two secrets into a repository's settings, but it's the setup you do once and never revisit for this particular error again.

Handling the credentials you now have

Once credentials exist and work, a handful of habits keep them from becoming the next incident rather than just the next how-to article. Never commit a credentials file, or an access key pasted into code, to any repository — public or private. Recent versions of the CLI's configure command will warn you if your credentials file has file permissions looser than the default of owner-read-write-only, which is worth paying attention to on a shared or multi-user machine. Rotate access keys periodically, and delete or deactivate any key you're not actively using rather than leaving it active "just in case" — an inactive key can't be used for API calls at all, which is the safest state for one you're not sure you still need. If you're ever unsure whether a key has already leaked, deactivating it first and asking questions second costs you a few minutes of reconfiguration; leaving it active while you investigate costs considerably more if the answer turns out to be yes.

When you've checked everything and it still fails

A short honest list, for the point where the obvious causes are ruled out. Confirm the AWS CLI itself is actually installed and on your PATH — aws --version should return a version string, not a "command not found" error; a broken or partial install can behave in ways that look exactly like a credentials problem. Check for a genuinely corrupted credentials or config file — stray characters, mismatched brackets, or an editor that silently added Windows line endings to a file the CLI expects in Unix format can all make a well-formed-looking profile unreadable. If you're behind a corporate proxy or VPN that intercepts EC2 metadata traffic, that can block the instance-role path specifically while everything else about the machine looks normal. And if none of that applies: delete the specific profile section entirely and recreate it from scratch with aws configure --profile name rather than continuing to edit it by hand — a clean rewrite catches invisible formatting problems that visual inspection won't.

Frequently asked questions

Why does aws configure list show my keys but I still get this error?

The keys being present isn't the same as them being valid. Run aws sts get-caller-identity to check whether AWS itself accepts them — an expired, deactivated, or deleted access key will still show up in aws configure list because that command only reports what the CLI found locally, not whether AWS still honors it.

Do I need to run aws configure if my code runs on EC2?

No, and generally you shouldn't. Attach an IAM role to the instance instead — the CLI retrieves temporary, automatically rotated credentials from instance metadata with no static keys stored anywhere on the machine.

What's the difference between the credentials file and the config file?

The credentials file (~/.aws/credentials) is meant for secrets — access keys. The config file (~/.aws/config) is meant for settings — Region, output format, role-assumption and SSO configuration. Both can technically hold credentials, but if the same profile appears in both, the credentials file's values win.

Why did this start happening after I set AWS_PROFILE?

AWS_PROFILE tells the CLI to look for a specific [profile name] section. If that section is misspelled, missing the word "profile," or doesn't exist in either file, the CLI won't fall back to your default — it fails outright. Confirm the section exists with the exact name before setting the variable.

Can I have credentials in both environment variables and the credentials file?

Yes, and it's common. Just remember environment variables always take precedence over the file for the same setting, so if a script or shell startup file has exported keys, those are what every command uses, regardless of what your file says.

Why does this happen specifically on aws s3 commands?

It's usually just the first command someone runs, not something specific to S3. The credential chain works identically for every AWS service; S3 commands only surface the issue first because they're often the reason someone installed the CLI in the first place.

How do I fix this inside a Docker container?

Either pass AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY as environment variables at run time, mount your host's ~/.aws folder in read-only, or, if the container runs on Amazon ECS, attach a proper IAM task role so no static keys are needed inside the container at all.

My SSO session used to work — why did it stop?

IAM Identity Center sessions expire on a schedule set by your administrators, often within a day. Run aws sso login --profile your-profile to reauthenticate; there's nothing wrong with your configuration itself.

I created access keys for the root user — why is that a problem?

Root user access keys carry unrestricted access to the entire AWS account with no permissions boundary, and AWS explicitly recommends against creating them at all. If you have one, delete it and switch to an IAM user or IAM Identity Center for programmatic access instead.

Where do I find "My Security Credentials" and what does it do?

It's the Security credentials tab on an IAM user's page in the IAM console (or the account-level page when viewing your own root account). It's where access keys, passwords, and MFA devices for that identity are created and managed.

How do I fix this with an assume-role profile?

Test the source profile by itself first with aws sts get-caller-identity --profile source-name. If that works but the role-assuming profile still fails, the issue is the target role's trust policy not permitting your source identity's ARN to assume it — that's fixed in the IAM console on the target role, not in your CLI configuration.

Why does the error look identical whether I have zero credentials or broken ones?

The credential chain is designed to try every source silently and only report a failure once every source has been exhausted, without distinguishing why each one failed. That's efficient for the CLI but unhelpful for you — which is exactly why checking aws configure list first, rather than guessing, saves the most time.

Is AWS CLI version 1 still supported?

It entered maintenance mode on July 15, 2026 and reaches end-of-support on July 15, 2027. New credential-chain improvements land in version 2 only, so if you're troubleshooting on version 1, upgrading is worth doing before digging further.

What does credential_process do?

It lets the CLI pull credentials from an external program you specify in the config file, rather than a static key — useful for integrating with a password manager, a hardware token, or a company-specific credential broker. It's an advanced option most people won't need for everyday use.

Can Windows and Mac/Linux share the same credentials file?

Not directly by file path — Windows looks in %USERPROFILE%\.aws\credentials while Mac and Linux look in ~/.aws/credentials, and those are different filesystems entirely on separate machines. You can copy the same file content between them, or set AWS_SHARED_CREDENTIALS_FILE to a synced location, but the CLI on each OS still reads from its own default path unless you override it.

What permissions should the credentials file have?

Owner read-write only, with no access for other users on the machine. Recent AWS CLI versions will warn you when running aws configure if the file's permissions are looser than that default, which is worth heeding on any shared or multi-user computer.

Revision note. Written August 2026, covering AWS CLI version 2 (2.36.x) across Windows, macOS, and Linux, including IAM Identity Center's PKCE-based SSO login, GitHub Actions OIDC federation, and the version 1 maintenance-mode timeline. This will need a look again once version 1 reaches its October 2027 end-of-support date or the credential provider chain itself changes. If you've spent your evening staring at this exact red line of text, you're not missing something obvious — the message just doesn't tell you which of six places it looked, and now you know how to ask it.

Related