メールが届かない時に確認すること

こんにちは、エンジニアの arinc0です。

以前、本番環境でBCCに設定したメールアドレスにメールが届かないという不具合が発生し、色々調査していたので備忘録として書かせていただきます。

書くこと

  • メールが届かない原因を調査した手順
  • 何が原因だったのか

結論

原因はステージング環境と本番環境で別々の問題でした。

ステージング環境でメールが届かなかった原因

  • 設定されているメールアドレスが正しいアドレスではなかったことが原因

本番環境でメールが届かなかった原因

  • 設定されているメールアドレスがサプレッションリストに追加されてしまっていたことが原因

原因を踏まえてメールが送れない時にまず確認すること

メールが送れない時は、まず下記を確認してみると良さそうです。

  • メールを送信するアドレスがメールを受け取れる正しいアドレスであるか確認すること。
  • SESを使用している場合は、メールを送信するアドレスがサプレッションリストに追加されていないこと。

調査①

調査①では、アプリケーションの設定を変更して動作確認しながら調査を進めていきました。

開発環境での確認

開発環境ではメール送信処理、BCCを設定する処理のそれぞれが正常に動作しているかを確認することにしました。

フレームワークでLaravelを使用しているので、ローカルの.envファイルを下記のように修正しました。

MAIL_DRIVER=log
# logに出力する場合は適当なアドレスでもOK
BCC_ADDRESS=test@example.com

上記の設定をすると、MAILの内容がログに吐き出されるようになります。
実際にログで確認してみると、ローカルではBCCが正しく設定されていることが確認できました。

上記の結果から、コード上の問題でメールが送れていないという可能性が低くなりました。

ステージング環境での確認

ステージング環境では、メールを受け取るアドレス自体に問題がないかを確認することにしました。

ステージング環境と本番環境では、MAIL_DRIVERとしてSESが設定されていました。
※ SESはAmazon Simple Email Serviceの略称です。

下記はステージング用の.env.stagingファイルの例です

MAIL_DRIVER=ses
BCC_ADDRESS=bcc-for-staging@example.com

受け取るメールアドレスに問題がある場合は、ステージング環境のBCCに対象のアドレスを追加してもメールが届かないと思われるので、追加して確認します。

MAIL_DRIVER=ses
# 本番用のアドレスを追加
BCC_ADDRESS=bcc-for-staging@example.com,bcc-for-production@example.com

上記変更をした後、メールを送信しました。

BCCに設定したアドレス(bcc-for-production@example.com)にメールが届かない想定でしたが、実際には届きました。
これにより、本番環境とステージング環境に差異があることがわかりました。

本番環境での確認

本番環境では、ステージング環境との差異を確認する為に、ステージングに設定されているアドレス(bcc-for-staging@example.com)を本番のBCC設定に追加することにしました。

下記はステージング用の.env.productionファイルの例です

MAIL_DRIVER=ses
# ステージング用のアドレスを追加
BCC_ADDRESS=bcc-for-production@example.com,bcc-for-staging@example.com

上記設定をしてメール送信テストを行ったところ、BCCに追加したbcc-for-staging@example.comにメールが届かないことが確認できました。

ここまでの動作から考えられる原因

ここまでの動作を踏まえた結果として、本番とステージングのSESの設定に差異があるのではないかと考えました。

調査②

調査②では、SESに関して調べながら調査を進めていきました。

SESの設定を確認

SESに関してはメールに関するサービスくらいの認識でしたが、とりあえず設定を見てみようと思いました。

マネジメントコンソールからSESを開き、サイドメニューの項目を一つずつ確認して行きました。

サプレッションリストという項目を見てみると下部にアドレスのリストがある画面が出てきました。

スクリーンショット 2022-10-26 10.14.43.png (146.7 kB)

リストの中にはBCCに設定されているが、メールが届かないアドレスが存在していた為この設定が怪しいのではないかと思いサプレッションリストに関して調べ始めました。

サプレッションリスト(Suppression list)

Amazon SES グローバルサプレッションリスト

公式のドキュメントを見てみるとと下記のように記載があります。

Amazon SES は内部のグローバルサプレッションリストを保持しています。これは SES によりバックグラウンドで運用と管理が行われています。SES のユーザーから送信された E メールがハードバウンスを起こすと、SES はバウンスを起こした E メールアドレスをグローバルサプレッションリストに追加します。グローバルサプレッションリストは、すべての SES のお客様に適用されるという意味で、グローバルです。つまり、別のカスタマーがグローバルサプレッションリストに登録されているアドレスに E メールを送信しようとした場合、SES はメッセージを受け付けますが、送信しません。これは、E メールアドレスが抑制されているためです。

補足を加えながら意訳します。

Amazon SES はグローバルサプレッションリスト(SESを使用しているユーザー共通のサプレッションリスト )を持っています。 そして、SESのユーザーから送信されたEメールが「宛先のメールアドレスが存在しない」のような原因で相手にメールが届かなかった場合には勝手にグローバルサプレッションリストに追加されます。 グローバルサプレッションリストに追加されているメールアドレスにE メールを送信しようとした場合、SES はメッセージを受け付けますが、送信しません。

つまり、サプレッションリスト ≒ メールを送信しないアドレスリストということになります。

※ ハードバウンスに関してもう少し詳しく知りたい方はこちらがわかりやすくておすすめです。

アドレスがグローバルサプレッションリストに残っている時間は、アドレスがハードバウンスを生成するたびに長くなります。アドレスは、グローバルサプレッションリストに最大 14 日間残ります。

14日間も追加されたままだと色々困ることがあると思います。
それを解消する為に、グローバルサプレッションリストの E メールアドレスを削除するようにリクエストする機能がありました。(現在はない)

現在は、アカウントレベルのサプレッションリストというものに置き換えられているみたいです。
※ 長くなってしまうので細かい説明を省きますが、グローバルサプレッションリストの内容を上書きできるものだと思ってもらえれば大丈夫です 。

原因と結果

本番

メールが届かない原因

本番環境でメールが届かないのは、サプレッションリストに追加されてしまっているのが原因でした。

サプレッションリストに関して調べることで、「BCCに設定しているがメールが届かないアドレス」がサプレッションリストに追加されており、その為メールが送信されないということがわかりました。

サプレッションリストに追加された原因

過去にハードバウンスしていたのが原因でした。

アカウントレベルのサプレッションリストを使用している場合、送信したメールがバウンスを起こすとグローバルサプレッションリストとアカウントレベルのサプレッションリストに追加されます。

グローバルサプレッションリストに追加されたアドレスはあらかじめ決められた期間が過ぎると勝手に削除されますが、アカウントレベルのサプレッションリストに追加されたアドレスは手動で削除するまで削除されません。

PJの関係者に確認したところ、BCCのアドレスを設定した段階ではメールアドレスが決まっていたがまだ有効になっていない状態だったようです。

簡単にまとめると下記のような流れでした。

BCCにアドレスを追加(この時アドレスが有効ではない)
↓
実際にメール送信処理が行われる(アドレスが有効ではないのでバウンスしてサプレッションリストに追加される)
↓
メールアドレスが有効になる(メールが受信できる状態になっているが、サプレッションリストに追加されているのでメールは送信されない)

結果

本番環境に関しては、サプレッションリストからBCCに設定しているアドレスを削除することでメールが届くようになりました。

ステージング環境

メールが届かない原因

そもそも有効ではないメールアドレスが設定されていることが原因でした。

ステージング環境も同様に、BCCに設定されているアドレスがサプレッションリストに登録されていました。
ですが、対象のアドレスを削除してもメールが届きませんでした。

そこで「そもそもこのメールアドレスは有効なのか、、、?」と考え、確認してみたところ有効ではないアドレスでした。

経緯としては、メール送信処理の中でアドレスがnullだとエラーで落ちてしまっていたので一旦仮のアドレスが設定されており、そのアドレスがそのまま変更されずに今に至るという感じでした。

結果

ステージングのBCCにステージングテスト用の有効なアドレスを設定することで、ステージングでもBCCに設定したアドレスでメールが届くことが確認できました!

まとめ

一概にメールが送れないと言っても、

- 受け取る側のアドレスの問題
- アプリケーション側の問題
- アプリケーションで利用しているサービスの問題

のようにいくつか切り分けができるなと感じました。

今回SESのサプレッションリストに関して知ることができたので、SESを使用していてメールが届かない時はまずサプレッションリストを確認しようと思いました!