error aws
AWS AccessDenied Error
Understanding AWS AccessDenied error - the IAM user or role does not have permission to perform the requested action on the resource.
What It Means
The AccessDenied error in AWS indicates that the IAM user, role, or service making the request does not have the necessary permissions to perform the requested action. This is AWS’s equivalent of an HTTP 403 Forbidden and is one of the most common AWS errors.
Common Causes
- IAM policy doesn’t include the required action
- Resource-based policy (S3 bucket policy, KMS key policy) denying access
- Service Control Policy (SCP) in AWS Organizations blocking the action
- Permissions boundary restricting the effective permissions
- Session policy limiting assumed role permissions
- Cross-account access not properly configured
- S3 bucket has Block Public Access enabled
- KMS key policy not granting access
- VPC endpoint policy restricting access
How to Fix
Identify the missing permission
# Check who you are
aws sts get-caller-identity
# Check the exact error message — it often tells you which action was denied
aws s3 ls s3://my-bucket/ 2>&1
# An error occurred (AccessDenied) when calling the ListObjectsV2 operation
# Simulate IAM policies (check what's allowed)
aws iam simulate-principal-policy \
--policy-source-arn arn:aws:iam::123456789012:user/myuser \
--action-names s3:ListBucket s3:GetObject \
--resource-arns arn:aws:s3:::my-bucket
Fix IAM policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
]
}
]
}
# Attach the policy to a user or role
aws iam attach-user-policy \
--user-name myuser \
--policy-arn arn:aws:iam::123456789012:policy/MyS3Policy
# Or for a role
aws iam attach-role-policy \
--role-name myRole \
--policy-arn arn:aws:iam::123456789012:policy/MyS3Policy
Fix S3 bucket policy
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCrossAccountAccess",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111111111111:role/ExternalRole"
},
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::my-bucket/*"
}
]
}
Debug with CloudTrail
# Find the denied API call in CloudTrail
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=ListObjects \
--max-results 5
# Check for "errorCode": "AccessDenied" in the results
Fix in application code (boto3)
import boto3
from botocore.exceptions import ClientError
s3 = boto3.client('s3')
try:
response = s3.get_object(Bucket='my-bucket', Key='file.txt')
except ClientError as e:
if e.response['Error']['Code'] == 'AccessDenied':
print("Access denied. Check your IAM permissions.")
print(f"Verify that your role has s3:GetObject on arn:aws:s3:::my-bucket/*")
raise
// AWS SDK v3 for JavaScript
import { S3Client, GetObjectCommand } from '@aws-sdk/client-s3';
const client = new S3Client({ region: 'us-east-1' });
try {
const response = await client.send(new GetObjectCommand({
Bucket: 'my-bucket',
Key: 'file.txt',
}));
} catch (error) {
if (error.name === 'AccessDenied') {
console.error('Check IAM permissions for s3:GetObject');
}
}
Related Errors
- AWS ValidationException - Request parameters are invalid (not a permissions issue).
- AWS ResourceNotFoundException - The resource doesn’t exist (not a permissions issue).