My users are trying to access objects in my Amazon Simple Storage Service (Amazon S3) bucket, but Amazon S3 is returning the error "HTTP 403: Access Denied." How can I troubleshoot this error?

To troubleshoot HTTP 403: Access Denied errors from Amazon S3, check the following:

  • Permissions for bucket and object owners across AWS accounts
  • Issues in bucket policy or AWS Identity and Access Management (IAM) user policies
  • User credentials to access Amazon S3
  • VPC endpoint policy
  • Missing object
  • Object encryption by AWS Key Management Service (AWS KMS)
  • Requester Pays enabled on bucket
  • AWS Organizations service control policy

Permissions for bucket and object owners across AWS accounts

If the AWS account that owns the S3 bucket is separate from the AWS account that owns the object, you might receive HTTP 403: Access Denied errors because the accounts don't have the correct permissions to each resource.

To check the bucket and object owners from the Amazon S3 console, review the Permissions view of the respective bucket and object. To check the bucket and object owners using the AWS Command Line Interface (AWS CLI), follow these steps:

1.    Run this AWS CLI command to get the S3 canonical ID for your AWS account:

aws s3api list-buckets --query Owner.ID

2.    Run this command to get the S3 canonical ID of the object owner:

aws s3api list-objects --bucket example-bucket --prefix index.html

Note: This example command shows a single object, but you can use the list command to check several objects.

3.    If the canonical IDs don't match, then the bucket and object have different owners.

If the bucket and object are owned by separate accounts, you can grant the bucket owner full permissions to the object by running one of the following AWS CLI commands with the --acl bucket-owner-full-control parameter:

 

aws s3 cp test.jpg s3://bucketname --acl bucket-owner-full-control
aws s3api put-object-acl --bucket bucket-name --key object-name --acl bucket-owner-full-control

If you need on-going cross-account permissions for the bucket and objects, you can create an IAM role with the permission to access objects. Then, you can grant another AWS account the permission to assume the IAM role. For more information, see Tutorial: Delegate Access Across AWS Accounts Using IAM Roles and How can I make sure that the bucket owner has access to resources that are copied or moved between Amazon S3 buckets owned by different AWS accounts?

Issues in the bucket policy or IAM user policies

Review the bucket policy or associated IAM user policies for any statements that might be denying access incorrectly. Check for any incorrect deny statements, missing actions, or incorrect spacing in a policy.

For deny statements, be sure to check for any conditions that deny access based on multi-factor authentication (MFA), encryption keys, a specific IP, or a specific VPC endpoint. For example, in the following policy, there is an explicit allow statement for public access to s3:GetObject. However, there is also an explicit deny statement for s3:GetObject that effectively prevents access to S3 objects unless the request is from a particular VPC endpoint. In this case, the deny statement always takes precedence. Be sure to check that the request for the object meets the condition—otherwise, it's expected that access is denied.  

{
"Version": "2008-10-17",
"Id": "PolicyForTest",
"Statement": [
{
"Sid": "Allow-Public-Access-To-Bucket",
"Effect":
    "Allow",
    
"Principal": "*",
"Action": "s3:GetObject",
"Resource": [
"arn:aws:s3:::example-bucket/*"
]
},
{
"Sid": "Access-to-specific-VPCE-only",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:GetObject",
"Resource":
    [
    
"arn:aws:s3:::example-bucket/*"
],
"Condition": {
"StringNotEquals": {
"aws:sourceVpce": "vpce-1a2b3c4d"
}
}
}
]
}

Note: If the IAM policy or bucket policy requires MFA, be sure that MFA is used in requests to Amazon S3. If you use the AWS CLI to test this, be sure that you configure AWS CLI to use MFA.

Users can also be denied access for actions that are missing from the policy. For example, if a user wants to modify the access control list (ACL) on an object, and the user's associated policy is missing the PutObjectAcl action, then the user receives an HTTP 403: Access Denied error. The following IAM policy doesn't allow the IAM user to modify the ACL:  

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AddCannedAcl",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::111122223333:user/Dave"
]
},
"Action":
[

"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::examplebucket/*"
]
}
]
}

Incorrect spacing in a policy can also deny access incorrectly. For example, in the Resource section of a policy, if you type "arn:aws:s3::: bucketname/*" or "arn:aws:s3::: bucketname/ object.jpg", then users are denied access to those resources because of the extra space. The extra space is evaluated incorrectly as "arn:aws:s3:::%20bucketname/*" or "arn:aws:s3::: bucketname/%20object.jpg".

User credentials to access Amazon S3

Verify the user credentials that you're using to access Amazon S3. The AWS CLI and AWS SDK must be configured to use the credentials (for example, access key and secret access key) of your IAM user role.

If you're using the AWS CLI, run this command to check the configured credentials:

aws configure list

If you're using a role associated with an instance, be sure that you associated the correct IAM role to the instance. Run this command to check:  

aws sts get-caller-identity

VPC endpoint policy

If you're using an Amazon Elastic Compute Cloud (Amazon EC2) instance to access Amazon S3, and that instance is routed to Amazon S3 using a VPC endpoint, be sure that the associated VPC endpoint policy includes the correct permissions to access your S3 buckets and objects.

For example, the following VPC endpoint policy allows access only to my_secure_bucket. If you're using this VPC endpoint, you are denied access to any other bucket.

{
"Statement": [
{
"Sid": "Access-to-specific-bucket-only",
"Principal":
    "*",
"Action": [
    
"s3:GetObject",
"s3:PutObject"
],
"Effect": "Allow",
"Resource": ["arn:aws:s3:::my_secure_bucket",
"arn:aws:s3:::my_secure_bucket/*"]
}
]
}

Missing object

If a requested object doesn’t exist in the bucket and the requester doesn’t have s3:ListBucket access, then the requester receives an HTTP 403: Access Denied error rather than the HTTP 404 Not Found error.

To determine if the HTTP 403 error is masking an HTTP 404 error, first check if the object exists in the bucket by opening the bucket from the Amazon S3 console, or by running the head-object AWS CLI command:  

aws s3api head-object --bucket example-bucket --key object.jpg 

Note: Be sure to replace the bucket and key values with the values related to your S3 bucket and object.

If the object is available in the bucket, then the HTTP 403 error isn't masking an HTTP 404 error, and you must verify other configuration requirements to resolve the HTTP 403 error.

If the object isn't available in the bucket, then the HTTP 403 error is masking an HTTP 404 error, and you must resolve the issue related to the missing object.

Object is encrypted by AWS KMS

If an IAM user is denied access to an object that the user has full permissions to, use one of the following ways to check if the object is encrypted by AWS KMS:

  • Use the Amazon S3 console to view the object. Then, choose the Properties view. Review the Encryption dialog box. If AWS-KMS is selected, then the object is KMS-encrypted. For more information, see How Do I View the Properties of an Object?
  • Run the following AWS CLI command to make a head-object request. If the command returns ServerSideEncryption as aws:kms, then the object is KMS-encrypted.  
aws s3api head-object --bucket example-bucket --key object.jpg

If the object is KMS-encrypted, be sure that the KMS policy and the IAM user policy both allow the following actions for the respective IAM user and KMS key:  

"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
]

Requester Pays enabled on bucket

If a bucket has Requester Pays enabled, and an AWS account that doesn't own the bucket tries to access the bucket, then access is denied if the correct parameter isn't specified in the request. For more information, see Requester Pays Bucket.

To check if Requester Pays is enabled, open the bucket in the Amazon S3 console, and then review the bucket's Properties view.

The following is an example AWS CLI command that contains the correct parameter to access a bucket with Requester Pays enabled:

aws s3 cp bucketname/objectname --request-payer requester

AWS Organizations service control policy

If you're using AWS Organizations, check the service control policies to be sure that access to Amazon S3 is allowed. For example, the following policy explicitly denies access to Amazon S3 and results in an HTTP 403 error.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Action": "S3:*",
            "Resource": "*"
        }
    ]
}

For more information on the features of AWS Organizations, see Enabling All Features in Your Organization.  


Did this page help you? Yes | No

Back to the AWS Support Knowledge Center

Need help? Visit the AWS Support Center.

Published: 2018-06-29