目次
まず結論:URLを作り直す前に署名時と送信時を比べる
Amazon S3のpresigned URLでSignatureDoesNotMatchが返るときは、署名を作った側と実際に送ったrequestで、HTTP method、署名対象のheader、query stringなどが一致しているか確認します。URLを再発行するだけでは、送信側が別のmethodやheaderを付けていれば同じ失敗を繰り返します。AWSは、system clockのずれ、proxyによるheader/queryの変更、URL生成時と利用時のrequest parameterの不一致を代表的な確認項目として挙げています。
403というHTTP statusだけでSignatureDoesNotMatchとAccessDeniedを同じ原因にしないでください。S3 responseのerror codeを読み、SignatureDoesNotMatch、AccessDenied、ExpiredToken、RequestTimeTooSkewed等を分けます。AWSのpresigned URL公式FAQではSignatureDoesNotMatchについてmethod、headers、query string、clock、proxyを確認し、AccessDeniedでは生成principalのpermissionやbucket policyも調べるよう案内しています。
まず安全に残す情報
失敗したresponseから、XML error code/message、HTTP status、request ID、発生時刻を記録します。Presigned URLには一時的なアクセス権を与える署名やcredential関連parameterが含まれ、AWSはこれをbearer tokenとして保護するよう勧めています。URL全文、X-Amz-Signature、credential、秘密鍵をissue、chat、一般ログへ貼らないでください。共有する必要がある場合はURLを伏せ、method、対象bucket/keyの識別情報を安全に記録します。
表は横にスクロールできます
| 記録項目 | 見る理由 | 公開ログに残す内容 |
|---|---|---|
| Error code / message | Signature mismatchかpermissionかを分ける | codeと機密を除いたmessage |
| HTTP method | GET/PUT等が署名時と同じか | method名 |
| Host / region | 対象endpointと署名regionが合うか | hostname/region。ただしURL queryを伏せる |
| Signed headers | clientが同じ値を送っているか | header名と安全な比較結果 |
| Query string | 署名対象parameterが改変されていないか | parameter名・差分だけ |
| 発行時刻 / 実行時刻 | clock driftや期限を切り分ける | timestamp |
| Request ID | AWS側サポート調査やログ相関に使う | Request ID |
一時的にログを詳しくする場合でも、URLやfile内容をそのまま出しません。presigned URLを保管したログ自体が、期限内にファイルへアクセスできる情報になり得ます。
URL生成時のrequest条件を確認する
発行側の実装・設定から、どの操作に対するURLかを確認します。AWSはpresigned URLを作る際にbucket、object key、HTTP method、expiration等を指定すると説明しています。アップロードなら一般にPUT、ダウンロードならGETなど、利用時のmethodを発行時と同じにします。単にURL文字列だけを別clientへ渡し、methodやheaderを推測で設定しないでください。
次を発行側で記録し、送信側と比較します。
-
使用したS3 bucketとobject key。
-
presigned URLが許可するHTTP method。
-
signing時に指定したRegionとS3 endpoint。
-
SignedHeadersに含まれるheader名と、その期待値。
-
Content-Type、checksum、暗号化等、clientが追加するheader。
-
expirationと、署名に使ったcredentialsの種類・有効期間。
-
requestを経由するproxy、gateway、HTTP libraryの有無。
Regionを間違えた場合にAWS SDKやendpointが別のhostへredirectする構成では、署名されたhostと最終request先が異なることがあります。署名付きURLを不必要に再構成せず、clientが受け取ったURLをそのまま使っているか確認します。URLのpath、queryのencoding・順序・値、object keyのspaceや記号も比較対象です。Query stringは署名へ含まれ得るため、parameterを削る、追加する、URL decodeして再encodeする処理を挟まないようにします。
Client requestとの差分を取る
送信側で実際に送ったmethodとheaderを確認します。たとえば発行時にContent-Typeを署名対象として指定したのに、clientが異なるContent-Typeを送れば一致しません。一方、どのheaderが署名対象かはURLのX-Amz-SignedHeadersや生成コードで確認し、すべてのheaderが必ず署名に含まれると決めつけないでください。AWSの案内に従い、生成時と利用時のrequest parameterをひとつずつ照合します。
表は横にスクロールできます
| 比較対象 | URL発行側 | 実際の送信側 | 不一致時の対応 |
|---|---|---|---|
| HTTP method | GET / PUT等の署名method | clientが送ったmethod | 発行methodと一致させる |
| Host / Region | 発行bucketのregion/endpoint | 実際の接続host | 正しいregionのendpointで発行する |
| SignedHeaders | 署名に含めたheader名 | 同じheaderを送ったか | header名・値・正規化を確認 |
| Content-Type | 発行時の指定有無と値 | clientの送信値 | 署名時指定があれば同値を送る |
| Query | 発行時parameter | client/proxy後のquery | 余分なparameterや改変を除く |
| Path / object key | 発行したkey | 実request path | encodingとpath変更を照合 |
| 時刻・期限 | 署名生成時刻、expiration | client clock、実行時刻 | NTP、credential期限、URL期限を確認 |
アップロードではSDKやHTTP clientが自動でContent-Type、checksum、transfer encodingなどを加えることがあります。これらが署名されたheaderに含まれているかを確認します。AWSが示す一般原則は「signed requestのmethod・headers・queryを生成時と利用時で一致させる」ことです。別のheaderが常に禁止という意味ではなく、実際の署名条件とS3のrequest要件に従います。
Clock、Credential、Proxyを分けて調べる
AWSはsystem clockが同期していない場合、署名時刻が不正となりSignatureDoesNotMatchを起こす可能性を案内しています。発行サーバーとclientの時計をNTP等で確認し、発行時刻・実行時刻をUTCで比較します。数分の差があれば常に同じ挙動になる、という独自の閾値は設定せず、S3 responseと署名条件で確認してください。
Presigned URLは生成時に指定した期限まで有効ですが、生成に使ったcredentialが先に失効すればURLもそれより早く無効になる場合があります。AWSは一時credentialを使うURLはcredentialの有効期間を超えて有効にならないと説明しています。期限切れなら通常はExpiredTokenやAccessDenied等別のerrorになる場合もあるため、error codeを見ずに署名不一致と同一視しないでください。
Corporate proxyやAPI gatewayを経由する場合、URL queryやheaderを変更していないか確認します。AWSは一部proxyがheader/query stringを変更し、signature mismatchを起こし得るため、proxyを介さない安全なテストを試すよう案内しています。通信経路を変えるときも、credentialが含まれるURLを安全に保ち、公開ネットワークや第三者へ不用意に送らないでください。
SignatureDoesNotMatchとAccessDeniedを分ける
SignatureDoesNotMatchは署名値の一致に関するエラーとして調べます。method、signed header、query、path、region、時間、proxyが候補です。AccessDeniedの場合は、署名されたrequestの主体に対象操作の権限があるか、bucket/access point policyが拒否していないかを確認します。AWSのFAQは、presigned URLを生成するIAM user/roleに対象操作のpermission(例:s3:GetObject)があること、およびbucket policyに明示的なdenyがないことを確認するよう案内しています。
表は横にスクロールできます
| Error codeの例 | 最初の調査先 | 先に避けること |
|---|---|---|
| SignatureDoesNotMatch | method、signed headers/query、region、clock、proxy | IAM policyを広げるだけで直そうとする |
| AccessDenied | 発行principalのaction permission、bucket/access point policy | 署名内容の問題と決めつける |
| ExpiredToken | 発行元credential/sessionの有効期限 | URL expirationだけを延長する |
| RequestTimeTooSkewed等 | system clock、発行時刻、request時刻 | error responseを保存せずURLを何度も作る |
同じ403でもpolicy変更が必要とは限りません。最小権限の範囲を維持し、具体的なerrorと対象操作に合わせて調査します。permissionを確認する作業はbucket ownerやAWS管理者と行い、診断目的でbucketをpublicにしたり、全actionを許可したりしないでください。
最小再現で再試験する
本番objectを使う前に、許可されたtest bucketや非機密objectで同じmethod・region・signed header構成を再現します。発行側とclient側の比較表を埋め、まず一つの差分だけ修正して再試験します。複数の条件を一度に変えると原因が分からなくなります。GETとPUT、Content-Type有無、proxy経由/非経由など、変更する条件を明示します。
再試験記録には、URLを伏せた状態で、error code、発行時と実行時のmethod、region、SignedHeaders、Content-Typeの一致有無、時刻、proxy有無、Request IDを記録します。成功しても、presigned URLの漏洩リスク、期限、対象object、許可された操作、再利用可否を確認します。AWSは期限まで同じpresigned URLを複数回利用できると説明しており、PUTの場合は指定keyに既存objectがあれば置き換わるため、アップロード再試行前には上書きの影響も確認してください。
確認チェックリスト
-
S3 XML responseのerror codeを確認した
-
URL全文・署名・credentialsを安全な場所へ保存した、またはログで伏せた
-
発行したbucket、object key、Region、endpointを確認した
-
発行methodと実際のHTTP methodが一致している
-
SignedHeadersのheader名と値を照合した
-
Content-Typeやchecksum等を実requestと比較した
-
Query stringとobject pathがproxy等で変わっていない
-
発行側とclientの時計を確認した
-
Presigned URLのexpirationとcredential期限を確認した
-
Proxyやgatewayを介さない安全な最小テストを検討した
-
AccessDeniedならpermission/policyを別調査した
-
PUT再試行で既存objectを上書きしないか確認した
-
公開bucket化や過剰なpermission付与をしていない
次に行うこと
responseのerror codeとRequest IDを控え、URLを共有せずに発行側のmethod、Region、SignedHeadersとclientの実requestを比較します。差分があれば一つずつ直し、最小限のtest objectで再試験します。条件が一致するのに失敗する場合は、clock、credential/session期限、bucket policy、proxy経路を確認し、必要に応じてAWSサポートへRequest IDを含む安全な診断情報を提供します。
実際のbucket、client library、発行コード、policyはこのガイドで確認していません。AWSの現行公式資料と環境のrequest logsで条件を照合し、原因を確認できるまで特定の修正を断定しないでください。
Sources
-
AWS, Download and upload objects with presigned URLs: https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-presigned-url.html(新しいタブで開く)
-
AWS re:Post, Troubleshoot SignatureDoesNotMatch for S3 presigned URLs: https://repost.aws/knowledge-center/s3-presigned-url-signature-mismatch(新しいタブで開く)
-
Checked: 2026-10-15
