AWS S3存储桶上传报错InvalidBucketAclWithObjectOwnership求助
问题现象
网站突然无法上传图片,抛出以下错误:
##### RightAws::S3Interface returned an error: 400 Bad Request <?xml version="1.0" encoding="UTF-8"?> <Error><Code>InvalidBucketAclWithObjectOwnership</Code><Message>Bucket cannot have ACLs set with ObjectOwnership's BucketOwnerEnforced setting</Message><RequestId>REQUEST</RequestId><HostId>ID$ ##### RightAws::S3Interface request: https://bucket.s3.amazonaws.com:443/ #### RightAws::AwsError (InvalidBucketAclWithObjectOwnership: Bucket cannot have ACLs set with ObjectOwnership's BucketOwnerEnforced setting):
此前功能正常,未做任何配置变更。曾收到AWS邮件通知,提及S3默认配置变更,但邮件说明仅针对新存储桶:
您好:
我们特此通知,自2023年4月起,Amazon S3将更改所有新S3存储桶的默认安全配置。在此日期之后创建的新存储桶,S3阻止公共访问将被启用,且S3访问控制列表(ACLs)将被禁用。
大多数S3使用场景无需公共访问或ACLs。对于大多数客户,无需采取任何操作。如果您有公共存储桶访问或使用ACLs的场景,您可以在创建存储桶后禁用阻止公共访问或启用ACLs。在这些情况下,您可能需要更新自动化脚本、CloudFormation模板或其他基础设施配置工具来配置这些设置。如需了解更多信息,请阅读AWS新闻博客[1]和此变更的新功能公告[2],或访问我们的S3阻止公共访问[3]和S3对象所有权禁用ACLs[4]用户指南。此外,请查看我们关于这些设置的AWS CloudFormation用户指南[5][6]。
已尝试的操作
- 存储桶需要公开访问,原ACL设置中授予了
Everyone组读取权限(包含存储桶和对象)。 - 尝试将对象所有权设置为“ACLs disabled (recommended)”时,收到错误提示:
无法应用存储桶所有者强制设置,因为您存在现有的存储桶ACL
如果要应用存储桶所有者强制设置,您必须从存储桶ACL中移除授予其他AWS账户或组的访问权限,并将这些权限迁移到存储桶策略
- 移除存储桶ACL恢复默认(仅保留桶所有者的完全控制权限),配置了如下存储桶策略:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "Stmt1380877761162", "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::bucketname/*" } ] }
- 成功将对象所有权设置为“ACLs disabled (推荐)”,但上传图片时仍抛出相同错误。
解决方案
核心原因
虽然已调整存储桶层面的ACL和对象所有权设置,但上传代码(RightAws库)在上传对象时仍在尝试设置对象级别的ACL,而当存储桶启用BucketOwnerEnforced(即ACLs disabled)模式时,不允许设置任何对象ACL,这直接导致了400错误。
具体修复步骤
修改上传代码:
- 找到使用RightAws上传图片的代码段,移除所有设置对象ACL的逻辑(比如代码中类似
acl: 'public-read'的参数必须删除)。 - 确保上传请求不包含任何与ACL相关的头部或参数,因为存储桶禁用ACLs后,所有对象所有权自动归桶所有者,公共访问由存储桶策略统一控制。
- 找到使用RightAws上传图片的代码段,移除所有设置对象ACL的逻辑(比如代码中类似
验证存储桶配置:
- 确认存储桶的阻止公共访问设置中,若需要公开访问,需关闭“阻止公共访问到存储桶和对象”“阻止公共和跨账户访问存储桶策略”“阻止跨账户访问存储桶策略”这三个选项(仅保留“阻止新的公共存储桶策略”可根据需求选择)。
- 确认对象所有权确实处于
ACLs disabled (BucketOwnerEnforced)模式。
验证存储桶策略:
- 替换策略中的
bucketname为实际存储桶名称,确保策略已保存生效。 - 可通过S3控制台“权限”页面的“策略模拟器”,测试
GetObject权限是否对所有用户开放。
- 替换策略中的
测试上传:
- 修改代码后重新尝试上传,确认错误是否消除。
内容的提问来源于stack exchange,提问作者Sara Fuerst

