S3 InvalidAccessKeyId "Does Not Exist": Every Fix

Logeshwaran
—

The S3 error InvalidAccessKeyId: The AWS Access Key Id you provided does not exist in our records means Amazon S3 cannot recognize the access key ID supplied with your signed request. Fix the credential source before changing your bucket policy: run aws configure list, inspect the effective environment, and use aws sts get-caller-identity to identify valid credentials. The counterintuitive detail is that your AWS console can work perfectly while the CLI uses a deleted key from an old environment variable; the two sessions may have nothing to do with each other.

⚡ Quick Answer

• CLI: aws configure list, then aws sts get-caller-identity.

• Console: IAM → Users → your user → Security credentials → Access keys. Inspect status using an authorized administrator identity.

• Workloads: Remove stale keys from environment variables and move CI or cloud applications to approved roles.

Continue with the effective-credential check before changing S3 policies.

Jake operates a neighborhood phone shop, and his booking page deployment uploads small image assets to S3. A fictitious $249.99 repair order in his shop is waiting for a fresh page, but the nightly release now fails on the first upload. That failure is frustrating because the AWS console still opens the bucket normally.

The site has not yet changed; the deployment runner is the component that needs diagnosis. A build job can keep an obsolete secret long after the person who originally created the key has moved on. Replacing the bucket policy would address the wrong layer of the problem.

Read the S3 error before changing a policy

You are trying to upload a file, fetch an object, or list a bucket, and the S3 response names InvalidAccessKeyId. This is an authentication problem: the access key ID presented in the signed request is not recognized as a usable key by the service. It is not a statement that your bucket policy lacks an Allow statement. Start with the credentials that actually signed that request.

The S3 error normally has HTTP status 403 Forbidden, with error code InvalidAccessKeyId and message The AWS Access Key Id you provided does not exist in our records. A typical CLI wrapper identifies the S3 operation as well, such as ListObjectsV2 or PutObject. The operation name tells you where authentication failed, not where you should add a policy.

An access key ID is an identifier, not the secret signing value that accompanies it. For permanent IAM user credentials, disabling or deleting the key prevents its continued use. For temporary sessions, the ID comes with a secret access key and a session token, and the three parts must stay together. A valid ID with an incorrect secret or token may produce a different error, so use the exact code as evidence.

The efficient diagnostic order is: identify the credential source, check whether the ID belongs to the intended identity, then inspect key status or temporary-session validity. After authentication works, address S3 authorization if the next response is AccessDenied. Keeping those stages separate prevents the common mistake of granting broad S3 access to a caller whose credentials are not valid.

An error occurred (InvalidAccessKeyId) when calling the ListObjectsV2 operation: The AWS Access Key Id you provided does not exist in our records.

Compare InvalidAccessKeyId, SignatureDoesNotMatch, and InvalidClientTokenId

If you see similar red error text from two different tools, compare the actual error codes rather than guessing that both need new S3 permissions. An unrecognized access key ID is distinct from a cryptographic signature mismatch. An invalid session token is yet another type of credential failure. Each one points toward a different part of your configuration.

SignatureDoesNotMatch means the signature calculated by the service differs from the one supplied. A wrong secret key, signing method, or altered signed request can be involved. If the access key ID itself is unrecognized, the service cannot proceed as though that ID names an authenticated principal, so the S3 diagnosis is different.

InvalidClientTokenId is often encountered while calling AWS Security Token Service or other services with unusable security credentials. It should not be mechanically substituted for S3’s InvalidAccessKeyId. When one program invokes STS first and another calls S3 directly, you may see different error labels for a broken credential setup.

After fixing the recognized-identity problem, you might receive AccessDenied. That is progress: the request can now be authenticated but lacks the permission, resource-policy allowance, or other conditions needed for the action. Record the transition rather than assuming the original problem somehow remains.

ErrorMeaningFirst action
InvalidAccessKeyIdS3 does not recognize the access key IDCheck effective key source and IAM inventory
SignatureDoesNotMatchCalculated signature differs from request signatureCheck secret, request signing, and input alteration
InvalidClientTokenIdCredential/session token rejected by an AWS serviceCheck session validity and token
AccessDeniedRequest is not authorized after authenticationReview identity and resource policies

Jake: "So if I can see the bucket in my browser, the bucket must recognize the key in my deploy script, right?"

Ethan: "Not necessarily. Your browser might use your SSO session while the script uses a deleted key from its own environment."

This is the step you want to run before you change anything else, and it takes you under a minute. You ask the CLI which credentials it is really using, then you ask AWS who it thinks you are. Everything after this section depends on what those two commands tell you.

Check which credentials AWS CLI is actually using

You know your named profile is correct, yet aws s3 ls still fails. The next question is not whether you typed --profile somewhere last week; it is which credential source the current command resolved. The AWS CLI can read explicit environment variables, named profiles, temporary sessions, and role providers. A value injected by the surrounding shell or CI system can change the outcome.

Run aws configure list to see the selected access-key source, credential origin, and Region. It masks the sensitive values while showing where the setting came from. Then run aws sts get-caller-identity to find the account and ARN associated with the resolved credentials. If STS fails because credentials are invalid, that failure is itself diagnostic; it does not prove an S3-only problem.

An important nuance is that an explicit CLI --profile option changes profile selection, while individual environment variables may override settings sourced from configuration files depending on the setting and invocation. Blanket slogans about profile precedence will mislead you; inspect the resolved values in the exact process. The shell where you troubleshoot must be the same environment, user, and runtime context as the failing tool.

Once the caller identity resolves successfully, compare its account with the intended bucket owner or deployment account. A successful STS response from the wrong account means you have valid credentials but may still lack access. A failed identity call with an unrecognized key means you should repair credentials before spending time on bucket policies.

aws configure list
aws sts get-caller-identity
aws configure list --profile deployment
aws sts get-caller-identity --profile deployment

Find environment variables overriding your intended profile

If your laptop works and a terminal tab suddenly fails, inspect the environment variables inherited by that process. AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_SESSION_TOKEN are the important credential inputs. A forgotten export from an earlier test can override credentials loaded from a shared file. In automated jobs, a secret from an old environment can be injected without appearing in the checked-in source.

On Linux or macOS, check whether the variable names are present without printing the secret values into the console or build logs. On Windows PowerShell, inspect the environment variable names or a masked version of the access key ID. Complete keys stay out of support tickets and screenshots. A key ID is less sensitive than the secret itself but is still unnecessary to expose publicly.

If stale environment credentials are selected, remove those variables from the current process or fix the source that sets them. Re-run aws configure list and then aws sts get-caller-identity. This second pass is essential because some scripts also load a .env file, Docker environment configuration, or CI secret mapping after the shell starts.

Be especially careful with mixed credential sets. An access key ID from one session combined with a secret from another can produce a signature failure. A temporary access key without the matching session token can produce authentication errors. Replace all components as one atomic credential set instead of changing individual variables until the error happens to disappear.

# Linux/macOS: check names without exposing the values
for name in AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN AWS_PROFILE; do
  if [[ -n "${!name:-}" ]]; then echo "$name: SET"; else echo "$name: absent"; fi
done

# Clear stale credentials from current shell
unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN
# Windows PowerShell: display only whether a value is present
"AWS_ACCESS_KEY_ID set: " + [bool]$env:AWS_ACCESS_KEY_ID
"AWS_SESSION_TOKEN set: " + [bool]$env:AWS_SESSION_TOKEN

# Remove stale credentials from this process
Remove-Item Env:AWS_ACCESS_KEY_ID -ErrorAction SilentlyContinue
Remove-Item Env:AWS_SECRET_ACCESS_KEY -ErrorAction SilentlyContinue
Remove-Item Env:AWS_SESSION_TOKEN -ErrorAction SilentlyContinue

Jake: "Why would an old value win over the profile I configured yesterday?"

Ethan: "Because the running process can receive environment credentials before it ever reads that profile. Inspect the process, not your memory of the setup."

Find deleted, inactive, or mistyped IAM access keys

When a key worked last month but stopped today, examine IAM key inventory from a separate, authorized administrator identity. An IAM user can have access keys in Active or Inactive state, and a deleted key no longer appears in that user’s active inventory. The application may still hold the original string long after an administrator rotated or removed it.

A simple copy-paste mistake can also change the submitted key ID. Compare the saved ID against the ID listed for the user, without displaying secret values. A trailing space or newline in a poorly handled environment variable or configuration template is worth investigating, although well-behaved tools may reject malformed values before S3 receives the request.

A key can also come from a completely different AWS account. That alone does not mean the key is unknown: valid cross-account credentials can authenticate and then be authorized or denied against resources. The real issue is whether the submitted ID still corresponds to a valid credential, and whether the principal is the one you intended to use.

For a permanently deleted IAM access key, there is no restore button or recovery process that brings back that credential pair. Create a replacement if long-term credentials are unavoidable, or migrate the workload to a role. Reusing a copied ID while changing only the secret value will not revive the old key.

Key situationWhat to inspectCorrect action
Deleted IAM user keyNo matching key in intended account inventoryCreate a replacement or use a role
Inactive keyIAM key Status is InactiveRe-enable only if authorized, or migrate
Typo/copy issueMasked ID differs from inventoryCorrect stored input
Valid key, wrong accountSTS returns unexpected AccountSwitch identity or arrange cross-account permissions
  1. Identify the key source in the failing process.
  2. Inspect the intended IAM user from an authorized administrator session.
  3. Compare the key ID and Active or Inactive status.
  4. Replace a deleted key or use a role.
  5. Re-run STS and then the S3 command.

Handle temporary credentials and IAM Identity Center sessions correctly

You logged into IAM Identity Center yesterday, and today a script says its AWS credentials are invalid. IAM Identity Center works by issuing temporary role credentials, not by turning an expired session into a permanent IAM user key. Reauthenticate through the appropriate SSO profile and let the CLI or SDK refresh the short-lived credential set through its supported provider.

Temporary credentials consist of access key ID, secret access key, and session token. All three belong to one session. If the token expires, if the role session ends, or if a token is omitted, calls fail authentication, although the exact error code can differ among S3, STS, and SDK validation paths. You cannot promise that every missing token is reported as InvalidAccessKeyId.

For CLI profiles configured with IAM Identity Center, run aws sso login --profile team-dev, then run aws sts get-caller-identity --profile team-dev. For scripts, prefer the profile or appropriate credential-provider chain instead of copying temporary values into a static secrets file. The provider can then obtain sessions in the way supported by that tool.

A CI runner is a poor place for a developer’s interactive SSO cache. Prefer an assigned role or OpenID Connect federation that supplies short-lived credentials for the job. If a runner hardcodes an old temporary key ID, restarting the pipeline alone will not create a valid new session; the authentication setup must be repaired.

aws sso login --profile team-dev
aws sts get-caller-identity --profile team-dev

Jake: "Can I just copy the three temporary values into the job and forget about them?"

Ethan: "Those values expire. Give the job a role provider that refreshes credentials instead of treating a temporary session like a permanent password."

Repair named CLI profiles without exposing secrets

You may have more than one account or role configured, so checking the default profile is not enough. Use the same profile that the failing S3 command selects. The configuration and credential files live under ~/.aws/ on Linux and macOS and under %USERPROFILE%\.aws\ on Windows. A process running as another operating-system user may read entirely different files.

Use aws configure list --profile deployment to inspect sources and aws sts get-caller-identity --profile deployment to validate the resulting identity. If a profile is SSO-backed, use the SSO login flow; if it assumes a role, fix the source profile or role assumption. Rewriting a whole credential file in response to a single bad source creates new problems; fix the one entry.

For a non-expired IAM user key, aws configure --profile deployment can update its values, but prefer federation for people and roles for workloads. Treat static keys as an exceptional dependency requiring inventory and rotation. Any file that stores keys needs restricted operating-system permissions and must stay out of source control.

After correcting the source, retry a safe S3 operation appropriate to the caller’s permissions. If identity validation works but bucket access fails, check S3 authorization separately. A test that attempts to list every bucket may fail on permissions even though credentials are valid, so keep insufficient S3 permissions and failed authentication apart in your head.

aws configure list --profile deployment
aws sts get-caller-identity --profile deployment
aws s3api list-objects-v2 --bucket example-deployment-bucket --max-keys 1 --profile deployment

Fix Boto3 Python credential selection

Your Python application may continue using a stale access key even though the terminal works. Boto3 has a credential-provider chain, and code-supplied credentials can take precedence over environment variables and shared profiles. A session created before configuration changed can also retain an older resolved credential provider. Inspect the actual process, not a different shell.

Build clients using a boto3.Session(profile_name="deployment") when you deliberately want a named development profile. In production on Lambda, EC2, or ECS, prefer the environment’s assigned execution or task role with no manually supplied static credentials. Supplying aws_access_key_id in a client constructor defeats that role-based approach.

Catch botocore.exceptions.ClientError and print the service error code rather than the entire signed request or sensitive environment. Boto3 credential-resolution failures such as NoCredentialsError are not the same as service-side InvalidAccessKeyId. If the SDK cannot find any credentials, the request may stop before it reaches S3.

You can inspect a resolved key ID in a tightly controlled diagnostic, preferably masking almost all characters, but keep secret keys and session tokens out of every log. The best functional test is an STS caller-identity call from the same session followed by the S3 operation, which tells you whether the failure is authentication or subsequent authorization.

import boto3
from botocore.exceptions import ClientError, NoCredentialsError

session = boto3.Session(profile_name="deployment")
try:
    who = session.client("sts").get_caller_identity()
    print("Account:", who["Account"], "Arn:", who["Arn"])
    s3 = session.client("s3")
    print(s3.list_objects_v2(Bucket="example-deployment-bucket", MaxKeys=1))
except NoCredentialsError:
    print("No credentials resolved")
except ClientError as exc:
    print("AWS error:", exc.response["Error"]["Code"])

Fix the JavaScript SDK v3 credential chain

If Node.js reports an S3 authentication error despite a working CLI profile, inspect what the Node.js process inherited. The AWS SDK for JavaScript v3 uses a default provider chain when you create an S3Client without explicit credentials. Environment variables, shared configuration, SSO, web identity, and runtime role sources are among the supported providers.

The SDK stops at a provider that supplies credentials, rather than continuing until S3 accepts a request. Therefore an old environment access key can win credential selection and still fail at the service. A successful credential resolution is not proof of successful authentication. Match the JavaScript process environment to the failing deployment.

In application code, use new S3Client({ region: "us-east-1" }) without hardcoding an access key whenever the runtime has a suitable identity. For development, configure AWS_PROFILE and use the supported shared or SSO profile. If you pass credentials explicitly, you own their refresh and correct session token.

For diagnosis, an STS client using the same credential provider can identify the caller when the credentials are valid. Keep raw server-side IAM user keys away from the browser SDK: browser-distributed credentials are exposed to the user. For browser uploads, a backend-generated presigned URL or an appropriately scoped identity mechanism is safer.

import { S3Client, ListObjectsV2Command } from "@aws-sdk/client-s3";
import { STSClient, GetCallerIdentityCommand } from "@aws-sdk/client-sts";

const region = "us-east-1";
const sts = new STSClient({ region });
const who = await sts.send(new GetCallerIdentityCommand({}));
console.log("Account:", who.Account, "Arn:", who.Arn);
const s3 = new S3Client({ region });
await s3.send(new ListObjectsV2Command({
  Bucket: "example-deployment-bucket", MaxKeys: 1
}));

Jake: "Would writing the secret key directly in JavaScript guarantee it uses the right one?"

Ethan: "It would guarantee another secret to rotate and protect. Use the SDK provider chain with the right execution identity."

Trace credentials in Terraform and infrastructure deployments

When terraform plan fails to read an S3 backend, distinguish backend authentication from the AWS provider used to manage resources. Backends and providers can have separate credential configuration. You may fix the provider block while terraform init still uses an obsolete environment key for the remote state bucket.

The failing operation tells you which configuration to inspect. An S3 backend failure during initialization suggests looking at the backend’s effective profile, role, and environment; a resource read failure during planning may involve the configured provider or an alias. A hardcoded credential in either place should be replaced with an appropriate role-based or profile-based mechanism.

Local development can use a named AWS profile, with AWS_PROFILE set for the Terraform process. CI can use federation or its assigned execution role. A reusable pipeline secret storing long-term IAM user credentials creates the same rotation and leak hazards whether the program is Terraform, the CLI, or an SDK.

When comparing local and CI behavior, record the account returned by STS in each execution environment and the name of the selected role. Logging those identifiers is usually enough to diagnose wrong-identity deployment errors. Keep session tokens, secret access keys, and full debug traces out of routine build output.

Where failure occursCredential source to inspectNext test
terraform init / S3 backendBackend role, profile, environmentSTS from same runner
terraform plan / AWS providerProvider block and environmentSTS with provider identity
GitHub Actions jobOIDC role or repository secretsIdentity probe in job
CodeBuild jobService role and environment overridesIdentity probe in build environment

Diagnose GitHub Actions and CodeBuild secrets in order

Your deployment passed on Monday and fails on Tuesday with InvalidAccessKeyId. That pattern often points to credentials embedded in the automation rather than anything changing in the S3 bucket. A team member may have deactivated an old key while the job still consumes a repository secret. The runner may also inherit a temporary token that has expired.

Inspect the workflow’s authentication step before its S3 upload step. Record whether it uses static secret environment variables, AWS role federation, or a profile. In CodeBuild, inspect the project’s service role and any environment-variable overrides. Supplying stale AWS_ACCESS_KEY_ID values can defeat the intended service-role credentials.

Run aws configure list and aws sts get-caller-identity inside the job, with credentials masked. If the identity call fails, isolate the authentication step. If it resolves to the wrong account, repair the role or secret mapping before investigating the S3 bucket policy. Make small changes and rerun a safe stage first.

After the deployment works with role federation, remove old repository or project secrets that contained unnecessary long-term keys. A CI job should obtain scoped, short-lived credentials whenever supported. This also reduces the effort of key rotation because there is no shared static credential to update across every workflow.

# In a CI step, run these before an S3 deploy:
aws configure list
aws sts get-caller-identity
aws s3 cp ./site/index.html s3://example-deployment-bucket/index.html

You know the rules; now watch them catch a real pipeline. Keep your own job log open beside this walkthrough, because you will likely spot your own stale key in the same place Jake spotted his.

Worked example: a deployment job keeps using a deleted key

Imagine a small online phone shop whose release pipeline uploads website assets to S3. The administrator rotated an IAM user’s access key and later deleted the old key. The developer ran aws sts get-caller-identity locally using a working role, so the developer assumed the pipeline was using that role too. The next job failed with InvalidAccessKeyId during the upload.

Inside the runner, aws configure list showed that credentials came from environment variables rather than the expected role provider. The workflow had an old repository secret called AWS_ACCESS_KEY_ID alongside a matching old secret access key. Both values still existed as text in CI, but the corresponding IAM key no longer existed.

The low-risk correction was to remove the static environment credential mapping and configure the runner to assume the intended deployment role through its approved trust relationship. The job then ran aws sts get-caller-identity, confirming the deployment role ARN, before uploading assets. If role federation was unavailable, the interim fix would be a controlled key replacement and immediate rotation plan, not a wider S3 policy.

This is an illustrative worked example rather than a claim that a particular deployment was tested. It explains why the CLI can work on a laptop while the same S3 command fails in automation. The key lesson is that the process launching the request defines which credentials are actually used; the source code alone cannot tell you.

# Example investigation output (illustrative, identifiers omitted)
$ aws configure list
access_key   ****************OLD1   env
secret_key   ****************OLD2   env
region       us-east-1              config-file

$ aws sts get-caller-identity
# Failed: the stale environment credential was revoked.

# Remove old environment mapping in the CI job, configure
# its approved role, then rerun sts and the upload.

Jake: "The pipeline had the old key, so do I have to open the S3 bucket to everyone?"

Ethan: "No. Replace the invalid credentials with an authorized deployment role; the bucket should stay private."

  1. Inspect the CI job credential environment without exposing secrets.
  2. Find the stale repository secret or environment mapping.
  3. Configure the approved deployment role.
  4. Run STS caller identity from the runner.
  5. Retry a controlled S3 upload.
  6. Remove the old static secret and audit other consumers.

Rotate an IAM user key without breaking running applications

If you must keep a long-term IAM user key, rotate it as a controlled change rather than deleting it and hoping workloads recover. IAM users can ordinarily have two access keys, allowing you to create a second while the first remains active. That overlap supports moving applications without interrupting every caller at once.

Create the new key under the intended user, store it securely, and update each known consumer. Use GetAccessKeyLastUsed to help identify recent consumers of the old key, but treat last-used information as a clue rather than a complete dependency inventory. A rarely running monthly job may not appear during your short validation period.

After consumers are migrated, set the old key status to Inactive rather than deleting it immediately. Observe whether a forgotten job fails, and restore it temporarily only if authorized and necessary for migration. Once the old key is demonstrably unused, delete it. Deletion is irreversible, and the secret access key is only available when the credential pair is created.

For a compromised or former employee’s key, use the incident-response priority instead of a leisurely rotation. Inactivate or revoke access promptly, investigate usage, remove unnecessary permissions, and deploy a fresh identity for the workload. The appropriate urgency depends on whether exposure or unauthorized use is suspected.

aws iam list-access-keys --user-name deploy-bot
aws iam create-access-key --user-name deploy-bot
aws iam get-access-key-last-used --access-key-id AKIAREPLACEWITHREALID
aws iam update-access-key --user-name deploy-bot --access-key-id AKIAREPLACEWITHREALID --status Inactive
aws iam delete-access-key --user-name deploy-bot --access-key-id AKIAREPLACEWITHREALID

List, disable, and delete keys with IAM CLI commands

When you need to determine whether a key is active, use an administrator identity that already has authority to inspect the IAM user. The affected application key may be invalid and cannot be used to administer itself. A successful inventory from another identity also avoids confusing authentication failure with a lack of IAM permissions.

list-access-keys lists key IDs and status for an IAM user; it does not reveal secret access key material. get-access-key-last-used provides the latest reported usage details. update-access-key changes a key between Active and Inactive; delete-access-key removes it permanently.

Use exact user names and key IDs copied from your authorized inventory, not from untrusted error text. In a multi-account organization, open the correct account before performing a key-management action. An administrator in account A cannot assume that an IAM user with the same friendly name in account B is the same identity.

Keep a change record explaining why a key was disabled, which applications were updated, and which role replaced it. The few minutes spent documenting a key change can prevent the next engineer from reintroducing an old credential into a secret store during an incident.

# Read-only inventory: use a separate authorized admin profile
aws iam list-access-keys --user-name deploy-bot --profile admin
aws iam get-access-key-last-used --access-key-id AKIAREPLACEWITHREALID --profile admin

Jake: "Could I delete the old key right away after making a new one?"

Ethan: "Deactivate it first when you have a controlled rotation window. That exposes any forgotten consumer before deletion becomes irreversible."

Understand why the AWS console works while application code fails

You can open the S3 console and browse a bucket while your application gets InvalidAccessKeyId. The console session and the code are frequently authenticated through completely different mechanisms. A human may have an active IAM Identity Center session while a local script uses a deleted IAM user key. Browser success does not validate the application’s credential pair.

First identify the code’s caller using the same execution environment. Next, compare it with the intended console session’s account and role. If code cannot call STS successfully, it has not reached the point where an S3 permission comparison would help. If it authenticates as a different identity, check that identity’s access separately.

Different machines and operating-system users may also have different AWS configuration files. A scheduled task running under a service account does not automatically read the interactive developer’s profile. Containers inherit only the environment and credential providers made available to them. This explains many failures that seem to appear without a source-code change.

Once the application uses the desired identity, evaluate S3 permissions and bucket ownership. A working console session cannot lend its rights to another principal just because both are operated by the same person. Explicit identity configuration is the bridge between a human workflow and a machine workflow.

Working consoleFailing codeLikely distinction
SSO role sessionOld static access keyDifferent authentication methods
Account A roleValid account B roleAuthentication works; authorization may fail
Interactive profileContainer environmentDifferent configuration source
Browser userService account jobDifferent operating-system identity

Handle a key owned by a former employee

If the error points to a key once assigned to a former employee, treat that identity as an operational and security issue rather than an ordinary broken configuration. Determine whether the key has already been revoked, whether it was shared across applications, and what permissions it once had. Reviving a personal IAM user key merely to make a deploy pass trades one outage for a bigger one.

Use an authorized administrator or security team member to inspect the key and user, recent usage, and relevant audit events. A disabled key may explain the current error, but the audit should also ask why business automation depended on an employee identity. Shared human credentials make offboarding and accountability harder.

Move the workload to a dedicated execution role or supported federation flow with least-privilege permissions. Update jobs one at a time, validate the new caller identity, and remove stored copies of the employee credential. If the organization suspects a leak, follow its incident-response process and review activity that occurred before the key was deactivated.

If the account itself is no longer under your control, you cannot recover the key or change its status from an unrelated account. Work with the authorized account owner or administrator. Creating a different IAM user in your account will not make an old key ID from the departed account valid.

When the ordinary fixes do not work

If you have removed stale environment variables, confirmed your profile, and checked IAM inventory, move from guessing to evidence collection. Record the exact service operation and error code, the process identity, whether credentials are permanent or temporary, and the credential provider source. Include the account and role ARN when STS resolves successfully.

Check whether the failing tool is running in a different container, build worker, virtual environment, or operating-system account than the shell you used for testing. Also check for hardcoded credentials in client constructors, old Docker secrets, and application configuration files. A correct command in one environment does not update the already-running process in another.

When the issue is still unclear, reproduce it with the smallest safe call from the same runtime and collect sanitized diagnostics. AWS CLI debug logs can include request metadata and potentially sensitive details, so handle them as restricted material and redact them before sharing. A secret access key or session token has no place in a support case.

An AWS Support request should state which credential source was intended, which source was actually selected, what GetCallerIdentity returned, and when the problem started. Support cannot restore a deleted access key’s secret or bypass identity controls, but those details can narrow an account-specific question far faster than a screenshot of the S3 error alone.

aws sts get-caller-identity
aws configure list
aws iam get-access-key-last-used --access-key-id AKIAREPLACEWITHREALID --profile admin

Jake: "If the former employee made the key, should we ask them to turn it on again?"

Ethan: "Move the automation to a company-controlled role and review the old key’s activity. A personal key is the wrong long-term dependency."

Verify the account and Region without blaming the wrong cause

If someone says the key belongs to another AWS account, ask two separate questions: is that credential actually valid, and is it authorized to use the requested S3 resource? A valid key from account B does not automatically cause InvalidAccessKeyId against a bucket in account A. Cross-account S3 access is possible when policies and other applicable controls permit it.

Use aws sts get-caller-identity to identify the authenticated account before investigating the bucket policy. If this call succeeds, the key is recognized for that session, and you should investigate authorization, endpoint, or request differences. If it fails, keep troubleshooting credential sourcing rather than adding S3 permissions.

S3 bucket Regions affect endpoints and request routing, but a wrong Region is not generally a reason that a genuinely active access key ID ceases to exist. Use aws s3api get-bucket-location only after you have working credentials and the required rights. A region-related redirect or signature error should be diagnosed on its own terms.

For production systems, capture the account and Region as separate deployment parameters. Mixing them together leads to troubleshooting folklore: people rotate valid keys because the bucket was elsewhere, or alter bucket policies because the runner held a deleted key. The exact error code and the result of STS remove that ambiguity.

Fix copied credentials and input sanitation carefully

If a new key fails immediately after you paste it, check how the values moved from their secure source into the consuming process. A trailing newline in a CI variable, a whitespace character, or a quoted string copied with literal quotation marks can alter the submitted key. The key ID field and secret field are different values, and neither should contain explanatory placeholder text.

Inspect the length and masked beginning or ending of the ID rather than printing the complete secret. In code, calling strip() on every part of a credential set is a patch, not a permanent solution; correct the source format instead. A configuration parser might trim the field while a different program preserves it, creating confusing inconsistency.

Temporary credentials add one more source of copy errors: their session token is long and easy to truncate in a secret manager or environment form. All three values must come from the same STS session. If you replace only the access key ID and leave the previous token, the authentication error may change rather than disappear.

Once you identify a corrupted copy, replace the credential using the approved secure mechanism. Record the consumer that held the malformed value so subsequent deployments stop restoring it. A successful test of the corrected secret from a developer shell is not enough; make sure the actual pipeline or application receives the new value.

Prevent the next credentials outage with roles and checks

When your immediate deploy works again, reduce the chance that the same failure returns next month. The strongest preventive step for applications running on AWS is to use attached roles and supported automatic credential providers rather than long-lived secrets. For external CI, use workload federation where supported. For developers, use IAM Identity Center profiles.

At deployment start, run a small identity probe such as aws sts get-caller-identity and compare the result with the expected deployment account and role. This is more reliable than checking that an environment variable exists. A variable can be populated with a revoked key and still pass a superficial presence check.

Add a controlled key inventory process for any remaining IAM user credentials. Track owner, use case, rotation plan, and recent activity, and remove unused credentials. Treat GetAccessKeyLastUsed as a pointer rather than a complete security audit, because it supplies limited most-recent-use information rather than the full sequence of requests.

Finally, keep authentication and authorization monitors distinct. An InvalidAccessKeyId error needs credential remediation; an AccessDenied error after successful authentication needs policy evaluation. That separation makes alerts actionable and prevents the emergency response from becoming a broad, unnecessary S3 permission grant.

Investigate error logs without leaking authentication material

When the error occurs in a deployment job, you need enough detail to correlate the request without revealing credentials. Capture the time, AWS operation, bucket identifier where appropriate, reported error code, and the selected credential provider. IAM access key IDs can help an authorized administrator locate a credential, but the full secret access key and session token have no place in build output.

CloudTrail and IAM access key usage information can assist in an investigation, subject to service coverage, event configuration, and retention. An invalid credential does not guarantee a useful authenticated principal record for the attempted S3 operation, however. Treat absence of a relevant audit entry as inconclusive, especially when the failing request was rejected before normal authorization processing.

If you enable AWS CLI debug logging, restrict access to the output and review it carefully before sending to another team. Debug output may reveal headers, endpoint details, request metadata, or other information you would not put into a public issue report. Start with aws configure list and a masked identity probe; use deeper logging only when those checks leave a genuine gap.

For a recurring failure, track which pipeline stage first produced InvalidAccessKeyId and what changed in its credential provider. This lets your team compare a failing run with a known-good run without uploading secret files for inspection. Include a rollback plan that restores a working role mapping, not a previously revoked key.

Plan key rotation for jobs that run only occasionally

Occasional jobs make key retirement harder because their credentials sit unused between releases. A monthly reporting job can keep an old key in a schedule or secret store while daily deployment checks all pass. If you deactivate that key without finding the monthly consumer, the next run fails in a way that looks sudden to its operator.

Build an inventory from owners, configuration repositories, CI secret mappings, and relevant account records. Last-used information is valuable but does not constitute a complete dependency graph. A key showing no recent use might belong to a quarterly task or disaster-recovery process. Verify the business purpose before deletion, and remove unnecessary workflows instead of preserving forgotten keys indefinitely.

For each application, update the credential source and test a representative operation under the new identity. Where possible, use a dedicated role with exactly the permissions required by that application. This reduces the impact of employee departures and eliminates the need for long-lived credentials in many workloads.

When rotation is complete, leave an auditable record of the new identity, the old key status, and the responsible team. A later InvalidAccessKeyId then has a short investigation path: check whether the caller is still using the retired ID, confirm the replacement role is being selected, and resolve the specific consumer.

Know when an S3 permission change becomes appropriate

After replacing invalid credentials, a user can receive AccessDenied from the same S3 command. That is not proof the credential fix failed; it is evidence you have moved into authorization. The next task is to determine which action the caller needs, whether identity policies allow it, and whether bucket or organization controls restrict it.

A deploy job uploading one site prefix often needs only narrowly scoped S3 write permissions to that destination. Granting AmazonS3FullAccess simply because the previous error mentioned S3 would broaden exposure and hide the original credential issue. Keep the role policy limited to the resources and operations that deployment genuinely requires.

If a bucket belongs to another account, its owner may need to allow the intended principal according to the applicable S3 resource and identity policy model. You still need recognized, active credentials before these policies are evaluated as expected. Cross-account access is a permissions design question, not a method to rehabilitate a deleted key.

The clean troubleshooting boundary is straightforward: first prove who you are with STS, then prove what that identity can do with a safe S3 request. A pipeline that checks both conditions reports useful failures and guides the next engineer toward the correct repair rather than a desperate policy edit.

Frequently asked questions about S3 InvalidAccessKeyId

What does InvalidAccessKeyId mean in Amazon S3?

S3 does not recognize the access key ID supplied with the signed request. Check which credentials signed that request, then inspect the intended IAM user or temporary session. Adding bucket permissions cannot make an unknown access key ID valid.

Is InvalidAccessKeyId the same as AccessDenied?

No. InvalidAccessKeyId indicates a problem recognizing the supplied credential identifier. AccessDenied generally indicates a recognized caller lacks authorization or is blocked by an applicable policy.

How is InvalidAccessKeyId different from SignatureDoesNotMatch?

InvalidAccessKeyId concerns the credential identifier. SignatureDoesNotMatch indicates a mismatch between the request signature and what the service calculates. A wrong secret key or altered signed request belongs in the signature investigation.

How does InvalidClientTokenId differ from an S3 invalid key error?

InvalidClientTokenId is a credential or token-related error commonly seen with STS and other AWS operations. S3 has its own error codes, including InvalidAccessKeyId. Examine the service and exact code rather than treating them as interchangeable.

Why does an AWS access key work in the console but not in code?

The console and the code may use different credentials. An interactive SSO session can be valid while the code uses a deleted IAM user key. Run STS caller identity from the code’s execution environment.

Can an access key be recovered after deletion?

No. A deleted IAM access key cannot be restored, and the original secret value cannot be recovered later. Replace it with a new credential or, preferably, move the workload to a role.

How do I find which AWS credentials the CLI is using?

Run aws configure list to show the credential source and aws sts get-caller-identity to identify a successfully authenticated caller. Run both in the same environment as the failing S3 command.

Can environment variables override my AWS profile?

Yes, environment credential variables can override values from shared configuration files in common setups. The exact CLI profile and option behavior matters, so inspect aws configure list in the invoking process.

How do I list IAM access keys for a user?

Use aws iam list-access-keys --user-name USERNAME with an authorized administrator identity. The command lists access key IDs and statuses but does not reveal secret access key values.

How do I deactivate an AWS IAM access key?

Run aws iam update-access-key with the user name, access key ID, and --status Inactive. First determine whether any live application still depends on the key, unless you are responding to a compromise that requires immediate revocation.

What if the key belongs to a former employee?

Use authorized administrative access to investigate and disable the former employee’s credential. Migrate business automation to a dedicated role or identity. Review usage and possible exposure rather than reviving a personal key.

Why does GitHub Actions get InvalidAccessKeyId?

The workflow may inject a deleted static key from repository secrets or use a stale temporary session. Inspect the identity-resolution step inside the runner and prefer OIDC role federation over permanent access keys.

Why does Terraform fail while aws sts works?

Terraform may be using a different credential source, especially between its S3 backend and AWS provider. Compare the exact process environment and backend configuration. Test identity from the Terraform runner rather than another terminal.

Can a wrong AWS Region cause InvalidAccessKeyId?

An incorrect Region can cause S3 endpoint, redirect, or signing problems, but it does not normally turn a valid access key ID into an unrecognized key. Test credential recognition with STS first, then diagnose Region issues separately.

Do temporary AWS credentials require a session token?

Yes. Temporary AWS credentials consist of an access key ID, secret access key, and session token. Use the complete matched set and obtain refreshed credentials when the session expires.

What is the safest long-term fix for invalid AWS keys in CI?

Use an approved role or workload federation mechanism that supplies short-lived credentials automatically. Add a caller-identity check before deployment and eliminate obsolete static secrets. This reduces rotation outages and accidental credential exposure.

When Jake’s shop deploys its next page, the important win is not simply suppressing an error message. It is knowing which identity signs the request, having a clean path to refresh that identity, and keeping the S3 bucket private while the deployment operates. If you still see InvalidAccessKeyId, return to the process that generated the request and trace the credentials from there. That approach is safer, faster, and much easier to maintain than changing access policies at random.

📌 If you keep one line from this page

An unrecognized S3 access key ID is a credential problem: identify the key that signed the request before touching your bucket policy.

Revision note. Written October 15, 2026, with aws configure list and sts get-caller-identity as the first two commands every time. Know thyself, says the old maxim; here it means know which key signed the request.

Related