🔔

HTTPSエンドポイントでAmazon SNSを受けるときの設計ポイント:4xxは配信失敗にも再試行にもならない

に公開

はじめに

HTTPS エンドポイントで Amazon SNS を受ける設計をしていると、配信の挙動と監視で押さえておきたいポイントがあります。結論として、エンドポイントが 4xx 系ステータスを返した場合、SNS は「配信失敗」とみなさず、再試行もしません。つまり見かけ上「成功」扱いになります。

公式ドキュメントの要点

  • エンドポイントが 200〜4xx 以外を返す、または約 15 秒でタイムアウトすると、SNS は配信失敗として扱い再試行します。
  • 逆に 4xx を返した場合は配信失敗にならず、再試行もされません。

※参考
https://docs.aws.amazon.com/ja_jp/sns/latest/dg/SendMessageToHttp.prepare.html

具体例

エンドポイントの前段にある WAF で、IP 制限ルールにより 403 を返したケースでも、SNS 側では「配信成功」扱いになります。
このため、CloudWatch メトリクス NumberOfNotificationsFailed では検知できません。

※NumberOfNotificationsFailed については Amazon SNS のメトリクスに関するドキュメント参照
https://docs.aws.amazon.com/ja_jp/sns/latest/dg/sns-monitoring-using-cloudwatch.html

なぜ重要か

「正しく届いていないのに、失敗にもカウントされない」ため、監視や再配信の期待と実態がズレます。
HTTPS サブスクリプションでは DLQ も使えないため、4xx を返す設計だとメッセージがサイレントに失われます。

推奨対策

1. 受信エンドポイントの設計

  • 署名検証など「受信の妥当性確認」に成功したら即 2xx を返し、以降の重い処理は内部キュー等で非同期化する
  • アプリ側の一時的失敗で 5xx/タイムアウトを返すと SNS の再試行対象になりますが、4xx を返すと再試行されない点に注意

2. WAF/フロントの通過ルール

  • SNS 用の専用パスを設け、該当パスは厳しい IP 制限ではなく、ヘッダー条件(例: x-amz-sns-message-type)で許可し、アプリ側で署名検証を必須化する

※参考
https://docs.aws.amazon.com/ja_jp/sns/latest/dg/sns-verify-signature-of-message.html
https://docs.aws.amazon.com/ja_jp/sns/latest/dg/http-header.html

  • バイパスが難しい場合は、WAF ログで当該パスへの 403 をメトリクス化・アラート化して可視化

3. 監視の再設計

  • NumberOfNotificationsFailed に依存しない
  • 代替案:
    • WAF/ALB の 4xx(特に 403)をパス指定でカウントしてアラート
    • アプリ側で「SNS 署名検証失敗」「購読確認の未完了」などをログ出力し、CloudWatch Logs Insights もしくはメトリクスフィルタで監視

4. アーキテクチャ選択の見直し

  • 高信頼が必要なら、HTTPS ではなく SQS サブスクリプションを使い、コンシューマからポーリングする方式を検討(リトライや DLQ が使える)

※参考
https://docs.aws.amazon.com/ja_jp/sns/latest/dg/subscribe-sqs-queue-to-sns-topic.html
https://docs.aws.amazon.com/ja_jp/AWSSimpleQueueService/latest/SQSDeveloperGuide/best-practices-error-handling.html

  • 既存の HTTPS を残す場合でも、内部でメッセージを一旦キューに積む設計にして欠落を減らす

まとめ

SNS は 4xx を「配信失敗」とみなさず、再試行も行いません。
WAF などで 403 が返っても成功扱いになるため、NumberOfNotificationsFailed では検知できません。
2xx 即応答+非同期処理、WAF ルールの工夫、ログベースの監視、必要に応じた SQS 化で、確実な配信と可観測性を高めましょう。

Discussion