Skip to content

S3バケットの「The bucket does not allow ACLs」エラー解決方法

問題の概要

AWS S3にファイルをアップロードする際に「The bucket does not allow ACLs」というエラーが発生する問題は、多くの開発者が遭遇する一般的な障害です。このエラーは、最新のAWS S3のセキュリティポリシー変更に起因しており、ACL(アクセス制御リスト)の使用が制限されているバケットに対してACL操作を試みた場合に発生します。

重要な注意点

AWSは2022年4月以降、新規作成されるS3バケットのデフォルト設定を「ACL無効(推奨)」に変更しました。これにより、明示的にACLを有効にしていない限り、ACL関連の操作はすべてブロックされます。

原因分析

このエラーが発生する主な原因は以下の通りです:

  1. バケットのオブジェクト所有権設定が「ACL無効」になっている
  2. コード内でCannedACL(定義済みACL)を指定している(例:S3CannedACL.PublicRead
  3. バケットポリシーとACL設定の間の競合

解決方法

方法1: バケットのACLを有効にする(推奨されない)

バケットのオブジェクト所有権設定を変更してACLを有効にすることができます。

AWSコンソールでの手順
  1. S3バケット一覧から対象バケットを選択
  2. 「アクセス許可」タブを開く
  3. 「オブジェクト所有権」セクションの「編集」ボタンをクリック
  4. 「ACLを有効にする」を選択
  5. 変更を保存
bash
# パブリックアクセスブロックを無効化
aws s3api put-public-access-block --bucket MY_BUCKET \
  --public-access-block-configuration 'BlockPublicAcls=false,
    IgnorePublicAcls=false,
    BlockPublicPolicy=false,
    RestrictPublicBuckets=false'

# オブジェクト所有権設定を変更
aws s3api put-bucket-ownership-controls --bucket MY_BUCKET \
  --ownership-controls 'Rules=[{ObjectOwnership="BucketOwnerPreferred"}]'
csharp
var fileTransferUtilityRequest = new TransferUtilityUploadRequest
{
    BucketName = bucketName,
    FilePath = filePath,
    StorageClass = S3StorageClass.StandardInfrequentAccess,
    PartSize = 6291456,
    Key = keyName,
    // CannedACLの指定を削除または空にする
    // CannedACL = S3CannedACL.PublicRead  // この行をコメントアウトまたは削除
};

セキュリティ上の注意

この方法は簡単ですが、AWSではACLの使用よりもバケットポリシーの使用を推奨しています。ACLを有効にするとセキュリティリスクが高まる可能性があります。

方法2: バケットポリシーを使用する(推奨)

AWSのベストプラクティスに従い、ACLの代わりにバケットポリシーを使用する方法です。

json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowSpecificUserFullAccess",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::<your-account-id>:user/<dedicated-s3-user>"
            },
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:ListBucket",
                "s3:DeleteObject",
                "s3:PutObjectAcl",
                "s3:GetObjectAcl"
            ],
            "Resource": [
                "arn:aws:s3:::<bucket>/*",
                "arn:aws:s3:::<bucket>"
            ]
        },
        {
            "Sid": "AllowPublicReadAccess",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::<bucket>/*"
        }
    ]
}

対応するC#コードでは、ACL指定を削除します:

csharp
var fileTransferUtilityRequest = new TransferUtilityUploadRequest
{
    BucketName = bucketName,
    FilePath = filePath,
    StorageClass = S3StorageClass.StandardInfrequentAccess,
    PartSize = 6291456,
    Key = keyName
    // CannedACLの指定は行わない
};

方法3: 既存オブジェクトの可視性を変更する

既にアップロード済みのオブジェクトに対してパブリックアクセスを有効にする必要がある場合:

コンソールでの操作方法
  1. S3バケット内の対象オブジェクトを選択
  2. 「アクション」→「ACLを使用して公開」を選択
  3. 「公開」ボタンをクリック
  4. 処理の完了を待つ

ベストプラクティス

  1. 最小権限の原則: IAMユーザーには必要な権限のみを付与する
  2. バケットポリシーの使用: ACLではなくバケットポリシーを使用してアクセス制御を行う
  3. 定期的な監査: バケットポリシーとアクセス権限を定期的に見直す
  4. エラーハンドリング: コード内で適切なエラーハンドリングを実装する

トラブルシューティング

  • 変更が反映されるまで数分かかる場合があるため、少し待ってから再試行する
  • IAMユーザーに適切な権限が付与されていることを確認する
  • バケットポリシーのJSON形式が正しいことを確認する

まとめ

「The bucket does not allow ACLs」エラーは、AWSのセキュリティ強化に伴う変更が原因で発生します。短期的にはバケットのACL設定を変更することで対処できますが、長期的にはAWSの推奨するバケットポリシーを使用したアクセス制御に移行することがより安全で持続可能な解決策となります。

どちらの方法を選択する場合も、セキュリティリスクを理解した上で適切なアクセス制御を実施することが重要です。