Skip to content

S3 バケットの InvalidBucketAclWithObjectOwnership エラー解決

問題の説明

AWS S3 バケットへのファイルアプロード中に次のエラーが突然発生する場合があります:

##### RightAws::S3Interface returned an error: 400 Bad Request
<Error><Code>InvalidBucketAclWithObjectOwnership</Code>
<Message>Bucket cannot have ACLs set with ObjectOwnership's BucketOwnerEnforced setting</Message>

このエラーは、オブジェクト所有権設定(Object Ownership)ACL(Access Control List)設定 の互換性問題が原因です。具体的には:

  • 2023年4月以降、新規作成されるS3バケットではデフォルトで BucketOwnerEnforced が有効化
  • BucketOwnerEnforced モードでは ACLが完全に無効 になります
  • 既存バケットでもバケットポリシーとオブジェクト所有権の整合性がチェックされるようになりました

エラーメッセージにあるように、BucketOwnerEnforced ではバケット所有者が全オブジェクトを強制的に所有します。この設定が有効なバケットに対しACLを使用した操作を行うと、このエラーが発生します。

解決方法

🛠️ 方法1: ACLを完全に無効化しバケットポリシーを使用

推奨されるアプローチ

AWSのベストプラクティスに沿い、ACLではなくバケットポリシーでアクセス制御を行う方法です。

  1. 既存のACLをすべて削除(バケットACL設定画面から)
  2. オブジェクト所有権を ACLs disabled(推奨)に設定
  3. バケットポリシーを設定(公開読み取りが必要なケース):
json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::your-bucket-name/*"
        }
    ]
}
  1. パブリックアクセスブロック設定を調整:
    • BlockPublicPolicyfalse に設定

⚙️ 方法2: ACLの使用が必要な場合の設定変更

やむを得ずACLを使用する必要がある場合は、オブジェクト所有権モードを変更します。

bash
# オブジェクト所有権モードを変更
aws s3api put-bucket-ownership-controls \
  --bucket your-bucket-name \
  --ownership-controls "Rules=[{ObjectOwnership=BucketOwnerPreferred}]"

# ACLを再設定
aws s3api put-bucket-acl \
  --bucket your-bucket-name \
  --acl public-read

🌐 フロントエンドアプリ公開時の特別設定

React Router等のSPAをホスティングする場合、ディレクトリパスへのアクセス許可が必要です:

json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": ["s3:GetObject"],
            "Effect": "Allow",
            "Principal": "*",
            "Resource": "arn:aws:s3:::frontend-bucket/*"
        },
        {  // ディレクトリスキャン用
            "Action": ["s3:ListBucket"],
            "Effect": "Allow",
            "Principal": "*",
            "Resource": "arn:aws:s3:::frontend-bucket"
        }
    ]
}

ListBucket アクセスを明示的に許可しない場合、ディレクトリパスへの直接アクセスが失敗することがあります。

☁️ CloudFormation ユーザー向け設定

AccessControl プロパティを削除し、代わりに公開設定を明示します:

yaml
Resources:
  MyS3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: my-bucket-name
      PublicAccessBlockConfiguration:
        BlockPublicAcls: false
      OwnershipControls:
        Rules:
          - ObjectOwnership: ObjectWriter
      WebsiteConfiguration:
        IndexDocument: index.html
        ErrorDocument: error.html

技術的背景

2023年4月の変更により、S3バケットのデフォルト設定が更新されました:

設定項目旧設定新設定
パブリックアクセスブロック無効有効
ACL利用可否有効無効 (BucketOwnerEnforced)

設計指針の変化

  • ACLは複数アカウント間でのアクセス管理が複雑になるため廃止推奨
  • バケットポリシーを使用した方がアクセス制御がシンプルに

バケット設定状態の確認方法

現在の設定はCLIで確認可能です:

bash
# オブジェクト所有権状態確認
aws s3api get-bucket-ownership-controls \
  --bucket your-bucket-name

# パブリックアクセスブロック設定確認
aws s3api get-public-access-block \
  --bucket your-bucket-name

トラブルシューティングポイント

  1. 設定変更後の反映に時間がかかることがある(最大数分待機)
  2. 複数設定が競合していないか確認(ポリシー+ACL)
  3. ログイン中アカウントが バケットの所有者であることを確認
  4. 公開アクセスが必要な場合 BlockPublicPolicy=false 必須