An AWS Identity and Access Management (IAM) user has permission to the s3:PutObject action on my Amazon Simple Storage Service (Amazon S3) bucket. However, when they try to upload an object, they get an HTTP 403: Access Denied error. How can I fix this?

If the IAM user has the correct user permissions to upload to the bucket, then check the following policies for any settings that might be preventing the uploads:

  • IAM user permission to s3:PutObjectAcl
  • Conditions in the bucket policy
  • Access allowed by an Amazon Virtual Private Cloud (Amazon VPC) endpoint policy

IAM user permission to s3:PutObjectAcl

If the IAM user needs to update the object's Access Control List (ACL) during the upload, then the user also must have permission to the s3:PutObjectAcl action in their IAM policy. For instructions on how to update a user's IAM policy, see Changing Permissions for an IAM User.

Conditions in the bucket policy

Review your bucket policy for the following example conditions that restrict uploads to your bucket. If the bucket policy has a condition and the condition is valid, then the IAM user must meet the condition for the upload to work.

Important: When you review conditions, be sure to verify that the condition is associated with an Allow statement ("Effect": "Allow") or a Deny statement ("Effect": "Deny"). For the upload to work, the user must comply with the condition of an Allow statement, or avoid the condition of a Deny statement.

Check for a condition that allows uploads only from a specific IP address, similar to the following:

"Condition": {
  "IpAddress": {
    "aws:SourceIp": "54.240.143.0/24"
  }
}

If your bucket policy has this condition, the IAM user must access your bucket from the allowed IP address.

Check for a condition that allows uploads only when the object is a specific storage class, similar to the following:

"Condition": {
  "StringEquals": {
    "s3:x-amz-storage-class": [
      "STANDARD_IA"
    ]
  }

If your policy has this condition, the user must upload objects with the allowed storage class. For example, the previous condition statement requires the STANDARD_IA storage class, so the user must upload the object with an AWS Command Line Interface (AWS CLI) command similar to the following:

aws s3api put-object --bucket my_bucket --key examplefile.jpg --body c:\examplefile.jpg --storage-class STANDARD_IA

Check for a condition that allows uploads only when the object is assigned a specific access control list (ACL), similar to the following:

"Condition": {
                "StringEquals": {
                    "s3:x-amz-acl":["public-read"]
                }
            }

If your policy has this condition, then users must upload objects with the allowed ACL. For example, the previous condition requires the public-read ACL, so the user must upload the object with a command similar to the following:

aws s3api put-object --bucket my_bucket --key examplefile.jpg --body c:\examplefile.jpg --acl public-read

Check for a condition that requires that uploads grant full control of the object to the bucket owner (canonical user ID), similar to the following:

"Condition": {
  "StringEquals": {
    "s3:x-amz-grant-full-control": "id=AccountA-CanonicalUserID"
  }
}

If your policy has this condition, then the user must upload objects with a command similar to the following:

aws s3api put-object --bucket my_bucket --key examplefile.jpg --body c:\examplefile.jpg --acl bucket-owner-full-control

Check for a condition that allows uploads only when objects are encrypted by a certain AWS Key Management System (AWS KMS) key, similar to the following:

"Condition": {
  "StringEquals": {
    "s3:x-amz-server-side-encryption-aws-kms-key-id": "arn:aws:kms:us-east-1:111122223333:key/*"
  }
}

If your policy has this condition, then the user must upload objects with a command similar to the following:

aws s3api put-object --bucket my_bucket --key examplefile.jpg --body c:\examplefile.jpg --ssekms-key-id arn:aws:kms:us-east-1:111122223333:key/*

Check for a condition that allows uploads only when objects use a certain type of server-side encryption, similar to the following:

"Condition": {
  "StringEquals": {
    "s3:x-amz-server-side-encryption": "AES256"
  }
}

If your policy has this condition, the user must upload objects with a command similar to the following:

aws s3api put-object --bucket my_bucket --key examplefile.jpg --body c:\examplefile.jpg --server-side-encryption "AES256"

Access allowed by a VPC endpoint policy

If the IAM user is uploading objects to Amazon S3 using an Amazon Elastic Compute Cloud (Amazon EC2) instance, and that instance is routed to Amazon S3 using a VPC endpoint, you must check the VPC endpoint policy. Be sure that the endpoint policy allows uploads to your bucket.

For example, the following VPC endpoint policy allows access only to other_bucket. If your bucket isn't listed as an allowed resource, then users won't be able to upload to your bucket using the instance in the VPC.

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

Did this page help you? Yes | No

Back to the AWS Support Knowledge Center

Need help? Visit the AWS Support Center

Published: 2019-03-01