画面には送信完了、相手の受信箱には何もない
お問い合わせフォームの送信ボタンを押すと、画面が切り替わって送信完了と表示されます。管理者宛の通知メールも受信箱に入っています。ところが、送信者宛に出したはずの自動返信が、相手のところに届いていない。エラー画面は出ず、サーバー側にも異常は記録されていません。
受信側によって結果が分かれることがあります。独自ドメインのアドレス宛には届き、Gmailのアドレス宛だけ届かない。届かなかったほうは、迷惑メールフォルダを開いても入っていません。
この症状で先に確かめるのは、原因ではなく、送信側が何を見ているかです。2026年7月29日、自社サイトのDNSレコードとお問い合わせフォームのソースを測りました。本番のフォームからメールは送っていません。調査は読み取りだけで終えています。
送信関数が返すのは配送結果ではありません
PHPでフォームを組む場合、送信にはmail関数か、日本語をそのまま扱えるmb_send_mail関数を使うことが多くなります。この関数は真偽値を返します。多くのフォームは、この戻り値を見て送信完了の画面へ切り替えています。
ただし、この戻り値が示しているのは、メールがサーバー上の配送プログラムに受け付けられたところまでです。受け付けられたあとに相手のサーバーが拒否しても、迷惑メールとして隔離しても、関数はすでにtrueを返し終えています。
送信完了の表示と、相手の受信箱に何もないことは両立します。どちらかが嘘をついているのではなく、見ている地点が違います。
自社のフォームは、自動返信の戻り値を捨てていました
自社サイトのフォーム処理は1つのファイルにまとまっていて、295行あります。管理者宛の通知は、mb_send_mailの戻り値を変数で受け取り、処理結果として呼び出し側へ返していました。
一方、送信者宛の自動返信を送っている行は、関数を呼び出したまま戻り値をどこにも代入していません。真偽値は返ってきていますが、受け取る側がいないのでその場で消えます。自動返信の送信に失敗しても、画面にもログにも何も残らない構成です。
管理者宛と自動返信で扱いが分かれているので、意図して捨てたのではなく書き足す過程で抜けたものだと考えていますが、確認できていません。いずれにせよ、届かない側の情報が最初から取られていないことは確かです。
差出人の作り方は分けてありました。Fromには自社のアドレスを固定で入れ、投稿者が入力したアドレスはReply-Toに置いています。エンベロープの差出人も、-fオプションで自社のアドレスを指定していました。フォームによっては、Fromに投稿者のアドレスをそのまま入れる作りがありますが、この形にはなっていません。
SPFのincludeは3回で終わる
SPFは、そのドメインのメールをどのサーバーから送ってよいかを、DNSに書いておく仕組みです。受信側はこれを読み、送ってきたサーバーが許可されているかを判定します。
id-techs.comのTXTレコードを引くと、v=spf1 include:_spf.heteml.jp ~all が返りました。includeは、別の場所に書いてあるSPFレコードを取り込むという指定です。取り込み先の _spf.heteml.jp を引くと、v=spf1 include:_spf01.heteml.jp include:_spf02.heteml.jp ~all でした。
SPFの評価には、DNSを引く回数の上限が10回あります。超えるとpermerrorという結果になり、レコードが書いてあっても判定に使われません。
この構成でたどるのは _spf.heteml.jp、_spf01.heteml.jp、_spf02.heteml.jp の3回です。上限には届いていません。SPFレコードの書き方そのものが原因だという線は、ここで消えます。
末尾は ~all でした。これはソフトフェイルといって、許可リストにないサーバーから送られてきた場合に、疑わしいが拒否までは求めないと宣言する書き方です。-all なら明確に拒否を求めます。
どちらにするかは、送信経路を全部把握できているかで決まります。把握しきれていない状態で -all にすると、正規のメールを自分で止めることになります。
DMARCのレコードにレポート宛先が入っていません
DMARCは、SPFや電子署名の判定に失敗したメールを受信側にどう扱ってほしいかを宣言する仕組みです。_dmarc.id-techs.com を引くと、v=DMARC1; p=none; が返りました。
p=none は、失敗しても受信側の扱いを変えなくてよいという宣言です。したがって、このレコードがあることで自動返信が止められているという説明は成り立ちません。DMARCが原因だという線も消えます。
残るのはその先です。DMARCにはruaという項目があり、ここにアドレスを書いておくと、受信側から認証結果の集計レポートが届きます。自社のレコードにruaは入っていません。自社ドメインを名乗るメールがどこかで認証に失敗していても、こちらには何も返ってこない状態です。
では足せばよいのかというと、そうはいきませんでした。id-techs.comのネームサーバーを引くと dns0.heteml.jp と dns1.heteml.jp が返ります。契約しているサーバー会社のネームサーバーを使っている間は、レコードを1件ずつ編集することはできず、SPFとDKIMとDMARCは自動で設定されると公式のドキュメントに書かれています(2026年7月29日確認)。
つまり、ruaを足すにはネームサーバーごと別の場所へ移す必要があります。TXTを1行書き足す作業ではありません。ここは設定を忘れていたのではなく、DNSをどこで持つかという契約の側で決まっていた部分です。
届かない事故に気づけるかどうかは、届かないこと自体より運用に効きます。公開したあとに何を見続けるのかという話はホームページは「公開してから」が本番。保守・運用がなぜ必要なのかに書いたので、ここでは戻ります。
Gmailが5,000件未満の送信者に何を求めているか
Gmailの送信者ガイドライン(support.google.com/a/answer/81126、2026年7月29日確認)は、要件を2段階に分けています。
すべての送信者に課されているのは、SPFまたは電子署名(DKIM)のどちらかを設定すること、送信元IPアドレスの正引きと逆引きのDNSレコードが有効であること、TLSで接続して送ること、迷惑メール率を0.3%未満に保つこと、RFC 5322に沿った形式であること、そしてGmailのFromヘッダーを騙らないことです。2024年2月1日から必須になっています。
1日に5,000件以上を送る場合は、これに加えてSPFと電子署名の両方、DMARCの設定、ワンクリックでの配信停止、FromヘッダーのドメインがSPFまたは電子署名のドメインと一致していることが求められます。
お問い合わせフォームが、この5,000件という線を超えることはありません。DMARCを設定していないから届かない、という説明は、Gmailが公開している要件からは支持されません。一方でFromヘッダーを騙らないことは、件数に関係なく全送信者の要件です。自動返信のFromに投稿者のアドレスをそのまま入れる作りは、ここに正面から当たります。
自社の電子署名についても確かめようとしました。ただしDKIMのレコードは、セレクタと呼ばれる名前が分からないと引けません。よく使われるセレクタ名を12個試した範囲では、該当するTXTレコードは返ってきませんでした。
署名されているかどうかは、DNSからは確認できていません。届いた1通のヘッダーにあるDKIM-Signatureの行を見るほうが確実です。
なお、迷惑メール率0.3%未満という基準は、送信側のソースやDNSレコードからは測れません。Postmaster Toolsに自分のドメインを登録し、Google側から見た数値を確認する必要があります。今回は測っていません。
直せるところと、私の側からは測れないところ
確定したのは、届かないことを検知できる箇所が、送信側の構成のどこにもないという点です。自動返信の戻り値は捨てられ、DMARCのレポート宛先は空でした。フォームが出す送信完了の表示は、配送の成功を根拠にしていません。
送信側で直せることもあります。自動返信の戻り値を受け取ってログに残せば、少なくともサーバーへの受け渡しに失敗した回は記録に残ります。ただし捕まえられるのはそこまでで、相手の受信箱に入らなかった回は、先に書いたとおりtrueを返して通り過ぎます。
Fromを自社ドメインに固定し、Reply-Toで投稿者へ返す形は、自社のフォームでは既にできていました。残るruaは、こちらの都合では足せません。ネームサーバーをどこに置くかという、記事1本の範囲を超える判断が先に要ります。
こちらからは測れないものもあります。受信側がそのメールをどう扱ったかは、実際に送って、届いた1通のヘッダーを開かないと分かりません。今回は本番のフォームからメールを出さない方針で調べたので、そこには踏み込んでいません。相手のメールサーバーが内部で使っている判定基準も、外からは分かりません。
同じ症状が出ているなら、確かめる順番があります。最初に、自分のフォームのソースを開き、送信関数の戻り値をどこかで受け取っているかを見てください。受け取っていなければ、失敗しても記録が残らないので、そこを直さないと以降の調査で手掛かりが出ません。
次に、コマンドプロンプトで nslookup -type=txt に自分のドメインを続けて実行し、SPFレコードの有無を見ます。同じ要領で _dmarc. を頭に付けたドメインを引き、ruaが入っているかを確かめます。
最後に、実際に届いた1通で判定結果を見ます。Gmailならメニューからメッセージのソースを表示し、Authentication-Resultsの行に spf、dkim、dmarc がそれぞれpassとfailのどちらで並んでいるか、FromとReturn-Pathのドメインが揃っているかを確かめてください。ここまでで、送信側と受信側のどちらに残っているかが分かれます。
原因が送信サーバーの配送構成にあると分かった場合は、先に契約中のサーバー会社の窓口へ問い合わせてください。送信ログを持っているのは制作会社ではなく、そちらです。読み取りだけで切り分けが止まった場合や、フォーム側の作りを直す必要が出てきた場合は、お問い合わせからご相談ください。
FAQよくある質問
- Qフォームで送信完了と表示されたのに、メールが届いていません。どこから見ればいいですか。
- A最初に、フォームの処理が送信関数の戻り値を受け取っているかを見てください。受け取っていなければ、失敗しても記録が残らないため、以降の調査で手掛かりが出ません。次にSPFとDMARCのレコードを引き、最後に実際に届いた1通のヘッダーでAuthentication-Resultsの行を確認します。
- QSPFとDMARCを設定すれば届くようになりますか。
- A設定していないことが原因だと確かめられた場合には有効です。ただしGmailが1日5,000件未満の送信者に求めているのは、SPFまたは電子署名(DKIM)のどちらかであって、DMARCは含まれていません(2026年7月29日確認)。設定の追加を先に決めず、どの容疑者が残っているかを測ってから決めてください。
- Q自動返信のFromに、問い合わせをした人のアドレスを入れてはいけないのですか。
- AGmailの送信者ガイドラインは、件数に関係なくすべての送信者に対して、GmailのFromヘッダーを騙らないことを求めています。投稿者のGmailアドレスをそのままFromに入れる作りは、この要件に当たります。差出人は自社のドメインに固定し、返信先はReply-Toで指定してください。
- Q迷惑メール率が基準を超えていないかは、どこで分かりますか。
- A送信側のソースやDNSレコードからは測れません。Postmaster Toolsに自分のドメインを登録し、Google側から見た数値を確認する必要があります。