awsseverity: workaround
AccessDenied

AWS AccessDenied — User/role is not authorized to perform action

AccessDenied: user is not authorized to perform <action>

85% fixable~10 mindifficulty: intermediate

Verified against AWS IAM docs (troubleshoot-access-denied), AWS SDK v3 error schema, AWS CloudTrail best practices · Updated April 2026

> quick_fix

The IAM user or role making the request doesn't have the required permission. Read the full error — AWS tells you exactly which action was denied (e.g., "s3:PutObject"). Attach a policy granting that action to the user or role.

// Example: inline policy granting s3:PutObject on a specific bucket
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": "s3:PutObject",
    "Resource": "arn:aws:s3:::my-bucket/*"
  }]
}

What causes this error

AWS IAM follows deny-by-default. Every API call is evaluated against the identity's attached policies, the resource policy (if any), and any SCPs from AWS Organizations. If no policy explicitly allows the action and no deny overrules an allow, AWS returns AccessDenied with the exact action name that was denied.

> advertisementAdSense placeholder

How to fix it

  1. 01

    step 1

    Read the full error for the action name

    The error format is: "User arn:... is not authorized to perform: service:Action on resource: ...". Copy that exact action string.

  2. 02

    step 2

    Identify the IAM identity making the call

    The ARN in the error tells you: iam::123456789012:user/alice or assumed-role/MyLambdaRole/i-xxxxx. Go to IAM → Users or Roles → that identity.

  3. 03

    step 3

    Check attached policies

    Does any attached policy Allow the denied action on the target resource? If not, attach an AWS-managed policy (e.g., AmazonS3ReadOnlyAccess) or write a least-privilege inline policy.

  4. 04

    step 4

    Test with IAM Policy Simulator

    Before re-running your code, use the IAM Policy Simulator (iam.aws.amazon.com/iam/home#/policies/sim) to confirm the user now has the permission.

  5. 05

    step 5

    For cross-account or SCP denies

    If the policy looks right but it still denies, check for a resource policy (e.g., S3 bucket policy) that explicitly denies your ARN, or an SCP from AWS Organizations that restricts the action at the account level.

Why AccessDenied happens at the runtime level

Every AWS API call routes through IAM's policy evaluation engine, which assembles all applicable policies (identity, resource, permissions boundary, session, and Organisations SCPs) into a decision context. The engine applies a deny-overrides-allow rule with deny-by-default: if any explicit Deny matches, the request is denied; if no Allow matches across all evaluated policies, the request is also denied. AccessDenied includes the principal ARN, action name, and resource ARN, but for some services (KMS, STS) returns an encoded message that must be decoded with sts decode-authorization-message to reveal the deciding policy.

Common debug mistakes for AccessDenied

  • Attaching a policy to the user instead of the role being assumed, when code runs in EC2/Lambda/ECS, the request principal is the role's session, not the user, so user-level policies are never evaluated.
  • Granting Allow on s3:GetObject but resource arn:aws:s3:::bucket, GetObject acts on objects, not the bucket, so the resource must be arn:aws:s3:::bucket/*; the bucket ARN denies everything object-level.
  • Assuming a policy is active immediately, IAM is eventually consistent and policy changes can take 30-60 seconds to propagate to all regions, so retries fail until propagation completes.
  • Forgetting the resource policy override, an S3 bucket policy with explicit Deny on a Principal beats any IAM Allow, and the user wonders why their admin role can't access the bucket.
  • Reading the truncated error and skipping the action name, devs assume it's a generic auth issue and rotate keys, when the action listed (e.g. kms:Decrypt) names exactly the missing permission.

When AccessDenied signals a deeper problem

Repeated AccessDenied across the team usually means permissions are managed reactively rather than from an inventory. Every new feature ships, fails in staging, someone bolts on a JSON statement, and the policy tree grows into a tangle that no one fully understands. The architectural fix is to generate IAM policies from infrastructure-as-code that declares the actions each service legitimately needs (Terraform, CDK, SAM with explicit policy templates), combined with CloudTrail-driven least-privilege tooling like aws-iam-policy-generator. This converts permissions from tribal knowledge into auditable code and stops the deny-fix-deploy loop.

Editor's take

This error tends to surface at the exact wrong moment: a startup's first production deploy, where the IAM role used in CI/CD was cloned from a developer's personal account and never audited against least-privilege. The deploy pipeline calls `s3:PutObject` to upload build artifacts, gets `AccessDenied`, and the team spends 40 minutes reading CloudTrail logs at 11pm the night before launch. In microservices environments on ECS or Lambda, the blast radius widens — one misconfigured task role silently breaks three downstream services before anyone correlates the logs.

Encountering this error and actually tracing it to a permissions boundary or an SCP (rather than just slapping `AdministratorAccess` on the role) is a meaningful skill signal. A junior dev hits it and adds a wildcard. A mid-level engineer reads the error message, pulls `aws iam simulate-principal-policy`, and grants the minimum required action. The senior who genuinely understands it checks whether an AWS Organizations SCP or a VPC endpoint policy is the real blocker — and knows to run `aws sts get-caller-identity` first to confirm which role is actually making the call, because assuming the role you think is active is its own failure mode.

The adjacent errors that typically cluster around this one: `NotAuthorized` from services that use their own auth vocabulary (like STS and SNS), `UnauthorizedOperation` from EC2, and `KMS AccessDeniedException` when the denied action is a key policy evaluation rather than IAM. Downstream, you'll often find `RequestExpired` or silent S3 403s that don't surface as exceptions in SDKs configured without response validation. When CloudTrail shows the principal as `AIDAEXAMPLE123`, cross-reference it against `aws iam get-role` — assumed-role sessions have a different ARN format and the mismatch is easy to miss.

By Bikram Nath · Curator · Updated April 2026

Frequently asked questions

Does AccessDenied mean my credentials are wrong?

No. That would be InvalidAccessKeyId or SignatureDoesNotMatch. AccessDenied means AWS knows who you are but the identity lacks the required permission.

Why does AccessDenied sometimes show "Encoded authorization failure message"?

For security, AWS masks the exact deny reason for some services. Decode it with `aws sts decode-authorization-message --encoded-message <base64>`.

How do I find the minimum required policy?

Enable CloudTrail and look at the API calls the identity tried. The CloudTrail event shows the exact action. Build a policy with just those actions.

disclosure:Errordex runs AdSense, has zero third-party affiliate or sponsored links, and occasionally links to the editor’s own paid digital products (clearly labelled). Every fix is cross-referenced against the official sources listed in the “sources” sidebar before it ships. If a fix here didn’t work for you, please email so we can update the page.