Amazon SES で存在しない宛先にメール送信した際のバウンス通知の内容を確認してみた

「存在しないドメインのメールアドレス」「ユーザーが存在しないメールアドレス」宛に Amazon SES からメール送信した際、SNS トピックへのバウンス通知がどのような内容になっているかを確認しました。

コンバンハ、千葉(幸)です。

Amazon SES によるメール送信でバウンスが発生した場合、それを適切に把握することは大切です。

バウンスには以下の2タイプがあります。

  • ハードバウンス
    • メールアドレスが無効であるなどの理由で永続的にバウンスされるメール
  • ソフトバウンス
    • 受信ボックスがいっぱいである、一時的にメールサーバーが使用不可となっていた、など一時的な問題でバウンスされるメール

ここで、「存在しないメールアドレス」宛に Amazon SES からメール送信した際のバウンスの内訳を確認したい機会がありました。ここでの「存在しないメールアドレス」とは「ドメインが存在しない」「ドメインは存在するがユーザーが存在しない」の両方を含みます。

Amazon SES でバウンスが発生した場合その内容を Amazon SNS トピックに通知できるため、どんな通知内容になるかを確認してみました。

バウンス結果のまとめ

今回は以下の宛先にメール送信を行いました。

  • ドメインが存在しないケース1:dummy1@example.com
  • ドメインが存在しないケース2:dummy2@⚫︎⚫︎⚫︎.⚫︎⚫︎⚫︎ *1
  • ドメインは存在するがユーザーが存在しないケース:dummy3@▲▲▲.jp *2
    • このメールアドレスのドメインではGmailを使用しています

それぞれの宛先に送信した際の結果は以下のとおりです。

送信先アドレス bounceType bounceSubType status 送信からバウンスまで
dummy1@example.com Transient General 4.4.7 約950分
dummy2@⚫︎⚫︎⚫︎.⚫︎⚫︎⚫︎ Transient General 4.4.7 約1,038分
dummy3@▲▲▲.jp Permanent General 5.1.1 約7秒

なお、送信に使用した Amazon SES の条件は以下のとおりです。

  • 東京リージョンの検証済み ID
  • サンドボックスから移動済み
  • コンソールの「テスト E メールの送信」より「カスタム」で宛先を指定

送信に使用したアイデンティティ

Amazon SES でメール送信する際には、アイデンティティ(ID)を作成・検証する必要があります。アイデンティティは E メールアドレスとして作成するか、ドメインとして作成するかが選択できます。

今回は E メールアドレスタイプのアイデンティティを作成しました。当該メールアドレスを、例示のため以降はsource@example.co.jpと呼びます。

Amazon_SES_bounce

アイデンティティはほぼデフォルト状態です。

項目 設定
DKIM 該当なし
カスタム MAIL FROM ドメイン なし
E メールのフィードバック転送 有効化
フィードバック通知 Bounce のみ有効
承認ポリシー なし
デフォルト設定セット なし

アイデンティティの通知設定

通知の設定は、アイデンティティの詳細画面より以下のように確認できます。

Amazon_SES_Bounce-5813475

「E メールのフィードバック転送」はデフォルトで有効になっており、バウンスや苦情のフィードバックが発生した際に E メールで通知を行います。今回の例で言えば、通知先はsource@example.co.jpです。

参考:Receiving Amazon SES notifications through email - Amazon Simple Email Service

フィードバック通知は、フィードバックタイプごとに SNS トピックにメッセージを送信します。今回はフィードバックタイプBounceを指定して、フィードバック通知を設定済みです。SNS トピックには E メールをサブスクライブしており、フィードバックイベントが発生すれば最終的にメール通知される構成になっています。

参考:Receiving Amazon SES notifications using Amazon SNS - Amazon Simple Email Service

Amazon SNS のフィードバック通知コンテンツ

Amazon SES のフィードバック通知により Amazon SNS に送信されるコンテンツの内訳は以下より確認できます。

特に、バウンスタイプについては以下のようにまとめられています。(ドキュメントの記述を一部省略して表現)

bounceType bounceSubType 説明
Undetermined Undetermined Amazon SES がバウンスの理由を判断できるだけの十分な情報が含まれていない。
Permanent General 受取人の E メールプロバイダーがハードバウンスの原因を示していない。
Permanent NoEmail E メールアドレスが存在しない。
Permanent Suppressed 最近の履歴でハードバウンスを生じているため、Amazon SES サプレッションリストに追加されている。
Permanent OnAccountSuppressionList アカウントレベルのサプレッションリストにあるので、このアドレスへの送信を抑制した。
Transient General 受取人の E メールプロバイダーは一般的なバウンスメッセージを送信した。
Transient MailboxFull 受取人の受信トレイが満杯である。
Transient MessageTooLarge 受信したメッセージが大きすぎる。
Transient ContentRejected 受取人のプロバイダーが許可しないコンテンツが含まれていたた。
Transient AttachmentRejected 受取人プロバイダーが許容しない添付が含まれていた。

Permanentがハードバウンス、Transientがソフトバウンスを表します。

冒頭でまとめた結果の一部を引用すると、以下の結果です。

ケース 送信先アドレス bounceType bounceSubType
ドメインが存在しない dummy1@example.com Transient General
ドメインが存在しない dummy2@⚫︎⚫︎⚫︎.⚫︎⚫︎⚫︎ Transient General
ユーザーが存在しない dummy3@▲▲▲.jp Permanent General

ドメインが存在しないケースではTransientと評価されています。

また、ユーザーが存在しないケースの場合、バウンスサブタイプがGeneralとなっています。NoEmailというサブタイプもあるのでそちらが記録されることも想像していたのですが、今回の検証結果では異なりました。

受信側のメールプロバイダーがどういったバウンスメッセージを返すかに依存する部分かと思います。

コンソールからのテスト E メールの送信

Amazon SES のコンソールから、テスト E メールを送信できます。(Amazon SES メールボックスシミュレーター)

画面の選択イメージは以下です。今回は以下のような指定でメール送信しました。

Amazon_SES_test

シナリオは複数から選択でき、選択したシナリオによって宛先が異なります。

シナリオ Eメールアドレス
配信の成功 success@simulator.amazonses.com
バウンス bounce@simulator.amazonses.com
苦情 complaint@simulator.amazonses.com
サプレッションリスト上の受信者アドレス suppressionlist@simulator.amazonses.com
自動応答 ooto@simulator.amazonses.com
カスタム 独自に指定

今回は「存在しないメールアドレス」に送信したいので、「カスタム」を選択しています。

参考:シミュレーターを使用した Amazon SES でのテストメール送信 - Amazon Simple Email Service

テストメールの送信の結果

テストメールの送信結果を見ていきます。

今回の例では、バウンスの結果として以下の通知が届きます。

  • E メールのフィードバック転送によるメール通知(宛先はsource@example.co.jp
  • フィードバック通知による SNS 経由のメール通知(宛先は SNS トピックにサブスクライブされたもの)

両者の通知はほぼ同時に届きます。冒頭に記載したとおり、「ドメインが存在しない」ケースの場合、通知が届くまで15時間以上かかりました。

前者の「E メールのフィードバック転送」のイメージは以下です。

Delivery_Status_Notification__Failure_

項目
件名 Delivery Status Notification (Failure)
From MAILER-DAEMON@ap-northeast-1.amazonses.com
送信元 e234-240.smtp-out.ap-northeast-1.amazonses.com

後者のフィードバック通知のイメージは以下です。

AWS_Notification_Message_sns

項目
件名 AWS Notification Message
From no-reply@sns.amazonaws.com
送信元 us-west-2.amazonses.com

後者のイベントの中身を、改行を加えた上でケースごとに確認していきます。

ケース1:存在しないドメインへの送信

{
  "notificationType": "Bounce",
  "bounce": {
    "feedbackId": "0106018acf75f2fe-aa9dbf3a-6a37-4504-bbd4-9159d22fd4b2-000000",
    "bounceType": "Transient",
    "bounceSubType": "General",
    "bouncedRecipients": [
      {
        "emailAddress": "dummy1@example.com",
        "action": "failed",
        "status": "4.4.7",
        "diagnosticCode": "smtp; 550 4.4.7 Message expired: unable to deliver in 840 minutes.<421 4.4.1 Unable to connect to remote host>"
      }
    ],
    "timestamp": "2023-09-26T03:08:48.000Z",
    "reportingMTA": "dns; e234-6.smtp-out.ap-northeast-1.amazonses.com"
  },
  "mail": {
    "timestamp": "2023-09-25T11:18:18.762Z",
    "source": "source@example.co.jp",
    "sourceArn": "arn:aws:ses:ap-northeast-1:000000000000:identity/source@example.co.jp",
    "sourceIp": "xx.xx.xx.xx",
    "callerIdentity": "cm-chiba.yukihiro",
    "sendingAccountId": "000000000000",
    "messageId": "0106018acc0fbf8a-50deaec7-c22b-45b7-8f18-2d940db84ab1-000000",
    "destination": [
      "dummy1@example.com"
    ]
  }
}

diagnosticCodeとしていわゆるエラーメッセージが確認できます。

smtp; 550 4.4.7 Message expired: unable to deliver in 840 minutes.<421 4.4.1 Unable to connect to remote host>

840 分も待つんだな……という学びがあります。

ケース2:存在しないドメインへの送信

{
  "notificationType": "Bounce",
  "bounce": {
    "feedbackId": "0106018acfc737ac-98d4145c-2925-49d7-9cb6-2a3125a0ccde-000000",
    "bounceType": "Transient",
    "bounceSubType": "General",
    "bouncedRecipients": [
      {
        "emailAddress": "dummy2@⚫︎⚫︎⚫︎.⚫︎⚫︎⚫︎",
        "action": "failed",
        "status": "4.4.7",
        "diagnosticCode": "smtp; 550 4.4.7 Message expired: unable to deliver in 840 minutes.<421 4.4.0 Unable to lookup DNS for ⚫︎⚫︎⚫︎.⚫︎⚫︎⚫︎>"
      }
    ],
    "timestamp": "2023-09-26T04:37:34.000Z",
    "reportingMTA": "dns; e234-6.smtp-out.ap-northeast-1.amazonses.com"
  },
  "mail": {
    "timestamp": "2023-09-25T11:19:50.537Z",
    "source": "source@example.co.jp",
    "sourceArn": "arn:aws:ses:ap-northeast-1:000000000000:identity/source@example.co.jp",
    "sourceIp": "xx.xx.xx.xx",
    "callerIdentity": "cm-chiba.yukihiro",
    "sendingAccountId": "000000000000",
    "messageId": "0106018acc112609-941219e0-ba5b-40ed-b301-865c1545e633-000000",
    "destination": [
      "dummy2@⚫︎⚫︎⚫︎.⚫︎⚫︎⚫︎"
    ]
  }
}

ケース1とほぼ同じ内容です。ただ、宛先がexample.comの場合と異なりそもそも DNS ルックアップができていない、という細かい違いがあります。

smtp; 550 4.4.7 Message expired: unable to deliver in 840 minutes.<421 4.4.0 Unable to lookup DNS for ⚫︎⚫︎⚫︎.⚫︎⚫︎⚫︎>

ケース3:ユーザーが存在しない場合

{
  "notificationType": "Bounce",
  "bounce": {
    "feedbackId": "0106018ad1486120-af114c55-0c0d-4e09-8635-cf49c1d4536f-000000",
    "bounceType": "Permanent",
    "bounceSubType": "General",
    "bouncedRecipients": [
      {
        "emailAddress": "dummy3@▲▲▲.jp",
        "action": "failed",
        "status": "5.1.1",
        "diagnosticCode": "smtp; 550-5.1.1 The email account that you tried to reach does not exist. Please try\r\n 550-5.1.1 double-checking the recipient's email address for typos or\r\n 550-5.1.1 unnecessary spaces. Learn more at\r\n 550 5.1.1  https://support.google.com/mail/?p=NoSuchUser ba5-20020a0561220c8500b004962ad9a1d6si618529vkb.0 - gsmtp"
      }
    ],
    "timestamp": "2023-09-26T11:38:16.000Z",
    "reportingMTA": "dns; googlemail.com"
  },
  "mail": {
    "timestamp": "2023-09-26T11:38:09.136Z",
    "source": "source@example.co.jp",
    "sourceArn": "arn:aws:ses:ap-northeast-1:000000000000:identity/source@example.co.jp",
    "sourceIp": "122.50.46.44",
    "callerIdentity": "cm-chiba.yukihiro",
    "sendingAccountId": "000000000000",
    "messageId": "0106018ad1484570-b35bc9b8-ae26-47d0-b9f1-d139308c57af-000000",
    "destination": [
      "dummy3@▲▲▲.jp"
    ]
  }
}

エラーメッセージには以下のように記録されています。受信側のEメールプロバイダがGmail を利用している環境なので、他の環境ではまた異なるメッセージが記録されるはずです。

smtp; 550-5.1.1 The email account that you tried to reach does not exist. Please try\r\n 550-5.1.1 double-checking the recipient's email address for typos or\r\n 550-5.1.1 unnecessary spaces. Learn more at\r\n 550 5.1.1 https://support.google.com/mail/?p=NoSuchUser ba5-20020a0561220c8500b004962ad9a1d6si618529vkb.0 - gsmtp

おまけ:バウンスのシミュレートの場合

今回の主旨とは外れますが、テストメールの送信の際にシナリオとしてbounceを選択した場合のイベントも確認しておきます。(「E メールのフィードバック転送」も他のケースと同様に届いています。)

{
  "notificationType": "Bounce",
  "bounce": {
    "feedbackId": "0106018acc0eca6c-8485ea19-6287-4d21-8b4b-4827f401342e-000000",
    "bounceType": "Permanent",
    "bounceSubType": "General",
    "bouncedRecipients": [
      {
        "emailAddress": "bounce@simulator.amazonses.com",
        "action": "failed",
        "status": "5.1.1",
        "diagnosticCode": "smtp; 550 5.1.1 user unknown"
      }
    ],
    "timestamp": "2023-09-25T11:17:16.000Z",
    "remoteMtaIp": "xx.xx.xx.xx",
    "reportingMTA": "dns; e234-4.smtp-out.ap-northeast-1.amazonses.com"
  },
  "mail": {
    "timestamp": "2023-09-25T11:17:14.991Z",
    "source": "source@example.co.jp",
    "sourceArn": "arn:aws:ses:ap-northeast-1:000000000000:identity/source@example.co.jp",
    "sourceIp": "xx.xx.xx.xx",
    "callerIdentity": "cm-chiba.yukihiro",
    "sendingAccountId": "000000000000",
    "messageId": "0106018acc0ec66f-4368cf8d-8f73-4fe7-8435-e969e24b5e12-000000",
    "destination": [
      "bounce@simulator.amazonses.com"
    ]
  }
}

終わりに

Amazon SES で「存在しない宛先」にメール送信した場合のバウンスの内容を確認してみました。

冒頭の表を再掲します。

送信先アドレス bounceType bounceSubType status 送信からバウンスまで
dummy1@example.com Transient General 4.4.7 約950分
dummy2@⚫︎⚫︎⚫︎.⚫︎⚫︎⚫︎ Transient General 4.4.7 約1,038分
dummy3@▲▲▲.jp Permanent General 5.1.1 約7秒

ドメインが存在しない場合はバウンスタイプがTransient(ソフトバウンス)であり、バウンス発生まで長時間かかることがわかりました。

また、ユーザーが存在しない場合でもバウンスサブタイプがGeneralで返されることがあることがわかりました。

手を動かさないとわからない部分だったので、満足しました。

Amazon SES に限った話ではありませんが、バウンスの管理は重要です。

バウンス数が多い場合はつど通知しても埋もれてしまう危険性が高いため、今回紹介したようなメール通知のみでの検知の仕方はあまり有効でないと思います。Virtual Deliverability Manager dashboard などの仕組みをご活用ください。

数がそこまで多くない場合はお手軽に試せるメール通知も悪くないでしょう。SNS トピックでサブスクリプションを作成する際にはサブスクリプションフィルターポリシーによってフィルタリングすることもできますので、例えばバウンスタイプがPermanentのものだけ通知する、というコントロールをすることである程度の量までは耐えうるかもしれません。

なんらか参考になれば幸いです。

以上、 チバユキ (@batchicchi) がお送りしました。

追記

実際にサブスクリプションフィルターでのフィルタリングを試してみました。

参考

脚注

  1. 「⚫︎⚫︎⚫︎.⚫︎⚫︎⚫︎」でマスクしている部分には、適当な文字列を組み合わせた実在しないドメイン名を指定しました。
  2. 「▲▲▲」でマスクしている部分には、実在するドメイン名を指定しました。