S3 署名付き URL へアクセスするとエラーになる時の対処方法

2021.11.19

困っていた内容

S3 の署名付き URL を作成してすぐにアクセスしたにもかかわらずアクセスエラーになってしまいます。

どうしたら正しくオブジェクトを取得できますか?

どう対応すればいいの?

いくつかの問題が考えられます。以下の順番に沿って問題の切り分けを行ってください。

1. 署名付き URL 作成時にバケット名を間違えている

確認ポイント
正しいバケット名を指定して再度署名付き URL を作成してください。

このケースでは下記のような NoSuchBucketエラーが返却されます。

<Error>
    <Code>NoSuchBucket</Code>
    <Message>The specified bucket does not exist</Message>
    <BucketName>not-exits-bucket</BucketName>
    <RequestId>SK732TEHY0E7FHAR</RequestId>
    <HostId>txJ0vO/b1IOueFBfBBAgh6I6cow4dXSLV+xhbpYcQEWnJa/1ogkzGm/b88RVy0eOh5HNIOP8mI0=</HostId>
</Error>

署名付き URL 作成時に、バケットの存在はチェックしません。
アクセス時にバケットが存在しなければこのエラーが返却されます。

2. 署名付き URL 作成時にファイル名を間違えている

確認ポイント
正しいファイル名を指定して再度署名付き URL を作成してください。

このケースでは下記のような AccessDeniedエラーが返却されます。

<Error>
    <Code>AccessDenied</Code>
    <Message>Access Denied</Message>
    <RequestId>VTGPPNATQVQCDABD</RequestId>
    <HostId>jPgu4l6UGpMMLhbH0sNStd188hUGPb8Mc7hlTeudWrjTo2sqaMbH0LzXoZqF0r/2/vGoygJjOuA=</HostId>
</Error>

バケット名を間違えたケースのように NoSuchFile が返却されるわけではありません。

NoSuchFile を返却するとファイルが存在する/存在しないことを探るヒントになってしまいます。
なので、オブジェクトにアクセスする権限がないことのみ返却していると思われます。

3. S3 署名付き URL を作成したクライアントの時計がずれている

確認ポイント
クライントの時計を確認し、正しい時刻に修正してください。

このケースでは下記のような AccessDenied エラーが返却されます。

執筆時点(2021-11-19)で 2022-01-01 の時刻となっていた場合

<Error>
    <Code>AccessDenied</Code>
    <Message>Request is not yet valid</Message>
    <X-Amz-Date>1641042858000</X-Amz-Date>
    <Expires>2022-01-01T14:14:18Z</Expires>
    <ServerTime>2021-11-19T13:14:44Z</ServerTime>
    <RequestId>SAWAHZHP2A652ZQM</RequestId>
    <HostId>9G4/HhXPM+R5mlUoe72WG5xtOF6Nv/rkFVfBBiULmXZoqmtH0pAVc/oabuCGw49W9yOHtwZ50dQ=</HostId>
</Error>

執筆時点(2021-11-19)で 2022-11-17 の時刻となっていた場合

<Error>
    <Code>AccessDenied</Code>
    <Message>Request has expired</Message>
    <X-Amz-Expires>3600</X-Amz-Expires>
    <Expires>2021-11-17T14:20:28Z</Expires>
    <ServerTime>2021-11-19T13:20:36Z</ServerTime>
    <RequestId>VB2DAMC20SC2GQ1N</RequestId>
    <HostId>/JZxZlicBUAKVc7sn2sNQKNQ0Pxc2IVdo6Y4ifpew1fi5Nc1qrzcZVBBHyFMJPZQV2sXNcpDcE8=</HostId>
</Error>

※ 署名の有効期限 expires-in はデフォルトの 1 時間(3600)で指定

4. S3 署名付き URL を作成した IAM ユーザー/ロールの権限に s3:getObject が不足している

確認ポイント
署名付き URL へアクセスしたタイミングで以下のリソースで s3:getObject 操作が許可されているか確認してください。

  • IAM ユーザー/ロールのポリシー
  • S3 バケットポリシー

IAM ユーザー/ロールで実際にオブジェクトへアクセスしてみることでアクセスできる状態であるか判断できます。

このケースでは下記のような AccessDenied エラーが返却されます。

<Error>
    <Code>AccessDenied</Code>
    <Message>Access Denied</Message>
    <RequestId>VTGPPNATQVQCDABD</RequestId>
    <HostId>jPgu4l6UGpMMLhbH0sNStd188hUGPb8Mc7hlTeudWrjTo2sqaMbH0LzXoZqF0r/2/vGoygJjOuA=</HostId>
</Error>

S3 署名付き URL は何のポリシーも持たないユーザー、ロールでも作れます。

アクセスの可否は署名付き URL へアクセスしたタイミングで決まります。
署名付き URL を作成した IAM ユーザー/ロールが IAM ポリシー、もしくはバケットポリシーで明示的に拒否されておらず、許可されていればアクセス可能です。

詳しく知りたい方は、下記ブログをご参考にしてください。

運用観点でのワンポイント

今回、比較的すぐに確認ができるファイル名やバケット名の誤り確認の切り分け順番を先に記載しました。

「4. S3 署名付き URL を作成した IAM ユーザー/ロールの権限に s3:getObject が不足している」の確認はポリシー量によっては大変です。

運用時のトラブルシューティングは切り分け手順が少ない(楽な)ものから先に試し、どこまで切り分けを行ったかをメモしていくと、解決まで短くなる可能性が高まります。

トラブルシューティングでは問題の切り分けを行うことがとても重要で、誰かに相談する際にも有用な情報となり得ますので、どなたかの参考になれば幸いです。

参考資料