AWS IAM Permission Denied Errors — How to Fix Every Variant (2026)
Getting 'Access Denied' or 'is not authorized to perform' errors in AWS? Here's how to diagnose and fix every IAM permission issue — EC2, EKS, Lambda, S3, and CLI.
AWS IAM errors are frustrating because the message tells you what failed but not why or how to fix it. Let's go through every common variant.
The Generic Error and What It Means
An error occurred (AccessDenied) when calling the DescribeInstances operation:
User: arn:aws:iam::123456789:user/dev-user is not authorized to perform:
ec2:DescribeInstances on resource: *
This tells you:
- Who:
arn:aws:iam::123456789:user/dev-user - What they tried:
ec2:DescribeInstances - On what:
*(all resources)
The fix is always: add a policy that allows this principal to perform this action on this resource.
Case 1: IAM User Missing Permissions
The simplest case — the user doesn't have a policy allowing the action.
Diagnose with IAM Policy Simulator:
aws iam simulate-principal-policy \
--policy-source-arn arn:aws:iam::123456789:user/dev-user \
--action-names ec2:DescribeInstances \
--resource-arns "*"Fix — add an inline policy or attach a managed policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:DescribeInstances",
"ec2:DescribeVpcs",
"ec2:DescribeSubnets"
],
"Resource": "*"
}
]
}aws iam put-user-policy \
--user-name dev-user \
--policy-name AllowEC2Describe \
--policy-document file://policy.jsonCase 2: EC2 Instance Role Missing Permissions
Your EC2 instance runs code that calls AWS APIs, but it gets AccessDenied.
Check the instance has a role:
aws ec2 describe-instances \
--instance-ids i-1234567890abcdef0 \
--query 'Reservations[].Instances[].IamInstanceProfile'If this returns null, the instance has no role — attach one.
Check what role the instance is using (from inside the instance):
curl -s http://169.254.169.254/latest/meta-data/iam/info | jq .InstanceProfileArnAdd the missing permission to the role:
aws iam attach-role-policy \
--role-name my-ec2-role \
--policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccessCase 3: Lambda Function Permission Denied
Lambda functions use an execution role. If the function calls S3, DynamoDB, etc., the execution role must have permission.
Check the execution role:
aws lambda get-function-configuration \
--function-name my-function \
--query 'Role'
# arn:aws:iam::123456789:role/my-lambda-roleAdd the missing permission to the role:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:UpdateItem"
],
"Resource": "arn:aws:dynamodb:us-east-1:123456789:table/my-table"
}
]
}aws iam put-role-policy \
--role-name my-lambda-role \
--policy-name AllowDynamoDB \
--policy-document file://policy.jsonCase 4: S3 Bucket Policy Blocking Access
Even if your IAM policy allows S3 access, the bucket policy can explicitly deny it.
Check the bucket policy:
aws s3api get-bucket-policy --bucket my-bucketLook for any explicit "Effect": "Deny" statements. Also check:
# Check if bucket blocks public/cross-account access
aws s3api get-bucket-policy-status --bucket my-bucket
aws s3api get-public-access-block --bucket my-bucketFix — add allow in bucket policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789:role/my-app-role"
},
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": "arn:aws:s3:::my-bucket/*"
}
]
}Remember: explicit Deny always wins over Allow — if there's a Deny anywhere in the chain (SCP, bucket policy, IAM policy), access is denied regardless of other allows.
Case 5: EKS — Pod Getting Access Denied to AWS Services
Your Kubernetes pod calls AWS APIs and gets AccessDenied. This is an IRSA (IAM Roles for Service Accounts) issue.
Check the pod's service account:
kubectl describe pod my-pod | grep "Service Account"Check if IRSA is configured on the service account:
kubectl describe serviceaccount my-sa -n my-namespace | grep eks.amazonaws.com
# Should show: eks.amazonaws.com/role-arn: arn:aws:iam::123456789:role/my-roleIf annotation is missing — add it:
kubectl annotate serviceaccount my-sa \
eks.amazonaws.com/role-arn=arn:aws:iam::123456789:role/my-eks-role \
-n my-namespaceCheck the IAM role's trust policy allows EKS OIDC:
aws iam get-role --role-name my-eks-role --query 'Role.AssumeRolePolicyDocument'The trust policy must have your EKS cluster's OIDC provider:
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::123456789:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:sub": "system:serviceaccount:my-namespace:my-sa"
}
}
}After fixing, restart the pod — it needs to pick up the new credentials.
Case 6: AWS CLI Using Wrong Profile/Region
Sometimes the error isn't a policy problem — you're authenticated as the wrong identity.
Check who you're authenticated as:
aws sts get-caller-identity
# {
# "UserId": "AIDAIOSFODNN7EXAMPLE",
# "Account": "123456789",
# "Arn": "arn:aws:iam::123456789:user/wrong-user"
# }Fix — use the correct profile:
aws sts get-caller-identity --profile prod-admin
export AWS_PROFILE=prod-adminCheck if MFA is required:
Some organizations require MFA for sensitive actions. The error looks like:
An error occurred (AccessDenied): Explicit deny in a service control policy
Use aws-mfa or assume a role with MFA:
aws sts assume-role \
--role-arn arn:aws:iam::123456789:role/AdminRole \
--role-session-name my-session \
--serial-number arn:aws:iam::123456789:mfa/my-mfa-device \
--token-code 123456Case 7: SCP (Service Control Policy) Blocking Access
If you're in an AWS Organization, SCPs can block actions even if your IAM policy allows them. SCPs are the outermost layer.
An error occurred (AccessDenied): Explicit deny in a service control policy
Check if SCPs apply:
aws organizations describe-effective-policy \
--policy-type SERVICE_CONTROL_POLICY \
--target-id <account-id>You need Organization admin access to view/modify SCPs. Contact your AWS admin.
Diagnosis Flowchart
Got AccessDenied?
│
▼
Who is the principal? (aws sts get-caller-identity)
│
├─ Wrong account/role → fix AWS_PROFILE
│
▼
Is it a bucket/resource policy issue?
│
├─ Yes → check bucket policy for explicit Deny
│
▼
Is there an SCP in the org?
│
├─ Yes → check with org admin
│
▼
Check IAM policy (simulate-principal-policy)
│
├─ Missing → add the permission
│
▼
Is it an EC2/Lambda/EKS role?
│
└─ Yes → check role + trust policy + IRSA annotation
Resources
- AWS Policy Simulator — Test policies without deploying them
- IAM Access Analyzer — Find overly permissive policies and unused access
- KodeKloud AWS Course — Hands-on AWS IAM labs in a real environment
- AWS Solutions Architect Associate — Deep IAM coverage, worth the certification
Stay ahead of the curve
Get the latest DevOps, Kubernetes, AWS, and AI/ML guides delivered straight to your inbox. No spam — just practical engineering content.
Related Articles
AWS ALB Showing Unhealthy Targets — How to Fix It
Fix AWS Application Load Balancer unhealthy targets. Covers health check misconfigurations, security group issues, target group problems, and EKS-specific ALB controller debugging.
AWS EKS Pods Stuck in Pending State: Causes and Fixes
Pods stuck in Pending on EKS are caused by a handful of known issues — insufficient node capacity, taint mismatches, PVC problems, and more. Here's how to diagnose and fix each one.
AWS VPC Networking: The Complete Guide for DevOps Engineers (2026)
Understand AWS VPC from the ground up — subnets, route tables, security groups, NACLs, VPC peering, Transit Gateway, and real-world architectures for production workloads.