S3 BucketOwnerEnforced ACL Conflict
AWS introduced significant security changes impacting S3 bucket configurations in April 2023, causing unexpected upload failures with errors like InvalidBucketAclWithObjectOwnership: Bucket cannot have ACLs set with ObjectOwnership's BucketOwnerEnforced setting
. This issue manifests as sudden upload failures even in previously working configurations.
Problem Explained
AWS disabled ACLs and enabled Block Public Access by default for new buckets starting April 2023. The BucketOwnerEnforced
Object Ownership setting:
- Disables all ACLs
- Makes bucket owner the exclusive object owner
- Rejects API requests containing ACL headers (e.g.,
public-read
) - Conflicts with bucket ACL configurations
The error occurs when:
- Your bucket has
BucketOwnerEnforced
enabled - Your application or infrastructure uses ACLs (in bucket settings or API calls)
- Upload requests include ACL headers like
x-amz-acl
Recommended Solutions
:fontawesome-solid-circle-check:{ .success } Solution 1: Migrate to Bucket Policies (Recommended)
Follow AWS's security best practice by discontinuing ACLs completely.
Steps
- Remove existing ACL grants
Delete all non-owner entries from bucket ACLs - Set Object Ownership
EnableBucketOwnerEnforced
via AWS Console or CLI:bashaws s3api put-bucket-ownership-controls \ --bucket YOUR_BUCKET_NAME \ --ownership-controls="Rules=[{ObjectOwnership=BucketOwnerEnforced}]"
- Configure public access
Allow public policies and apply bucket policy:bashaws s3api put-public-access-block \ --bucket YOUR_BUCKET_NAME \ --public-access-block-configuration "BlockPublicAcls=false,BlockPublicPolicy=false"
- Apply bucket policy
Use this policy for public read access:json{ "Version": "2012-10-17", "Statement": [ { "Sid": "PublicReadGetObject", "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*" } ] }
- Remove ACL headers from upload requests
Ensure SDK/client requests omit ACL parameters likepublic-read
:fontawesome-solid-gear:{ .manual } Solution 2: Re-enable ACL Support
Use this approach if you require ACLs or can't modify application code immediately.
Not Recommended
This retains legacy ACL behavior which AWS plans to deprecate
# 1. Allow ACL usage
aws s3api put-bucket-ownership-controls \
--bucket YOUR_BUCKET_NAME \
--ownership-controls="Rules=[{ObjectOwnership=BucketOwnerPreferred}]"
# 2. Set bucket ACL
aws s3api put-bucket-acl \
--bucket YOUR_BUCKET_NAME \
--acl public-read
For CloudFormation users:
Resources:
ExampleBucket:
Type: AWS::S3::Bucket
Properties:
OwnershipControls:
Rules:
- ObjectOwnership: BucketOwnerPreferred
PublicAccessBlockConfiguration:
BlockPublicAcls: false
Critical Fixes for Specific Use Cases
Single-Page Applications (SPAs)
Add ListBucket
permission for client-side routing:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::BUCKET/*"
},
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::BUCKET"
}
]
}
Upload Failures Persisting After Changes
Verify your upload code omits ACL headers. Common offenders:
- SDK parameters like
ACL='public-read'
(Boto3/Python) x-amz-acl
headers in REST API calls- CLI flags like
--acl public-read
Explanation of Key Changes
The root conflict arises from AWS security enhancements:
Setting | Impact |
---|---|
BucketOwnerEnforced | Disables all ACLs; requires bucket policies |
ObjectWriter | Allows object-level ACLs (legacy behavior) |
BlockPublicPolicy=false | Permits public bucket policies when using BucketOwnerEnforced |
Why This Changed
AWS deprecated ACLs as they grant coarse-grained access and complicate permission management. Bucket policies provide more secure, granular control via IAM principles rather than global permissions.
Best Practices
- Replace ACLs with bucket policies in all new projects
- Audit existing buckets via S3 console > Permissions tab
- Remove
ACL
parameters from all SDK/client code - Enable
Block Public Access
except where required
Configuration path: S3 Bucket > Permissions > Object Ownership
Adopting these solutions resolves the ACL conflict while aligning with AWS security standards. Migrate to bucket policies for sustainable configurations.