2026年9月14日
2026年9月14日
WordPressのwp_mail()でメールが送れない原因と直し方|エラー内容の確認からSMTP化まで
WordPressは、問い合わせフォームの通知、ユーザー登録、パスワード再設定などのメールを wp_mail() 関数で送ります。wp_mail() は内部でPHPMailerを使い、初期状態ではサーバーのPHPの mail() 関数(実際にはサーバーの sendmail や Postfix)にメールを渡します。
メールが届かないときは、「WordPressがメールを渡せていない」のか「渡せたが、その先で止まっている」のかを最初に分けると、原因を早く絞れます。この記事では、その切り分けの手順と、よくあるエラーごとの直し方を説明します(WordPress 6.9 のソースコードで確認、2026年10月時点)。
手順1:wp_mail() の戻り値を確かめる
wp_mail() は、PHPMailerがメールを送信処理に渡せたら true、失敗したら false を返します。WP-CLI が使える場合は、次のコマンドで管理者のメールアドレスにテストメールを送れます。
wp eval 'var_dump( wp_mail( get_option( "admin_email" ), "wp_mail test", "This is a test." ) );'
bool(false):WordPress側で送信に失敗しています。手順2でエラーの内容を記録しますbool(true):サーバーのメール送信プログラムやSMTPサーバーには渡せています。届かない原因はその先にあるので、「trueなのに届かないとき」に進みます
true は「送信処理に渡せた」という意味で、「相手に届いた」という意味ではありません。
手順2:wp_mail_failed でエラーの内容を記録する
wp_mail() が失敗すると、WordPressは wp_mail_failed アクションを実行し、PHPMailerのエラー文を入れた WP_Error を渡します。これをログに書くコードを mu-plugin(置くだけで常に読み込まれるプラグイン)にします。wp-content/mu-plugins/ フォルダーを作り(なければ)、次の内容で mail-error-log.php を置きます。
<?php
/**
* Plugin Name: wp_mail エラー記録
* Description: wp_mail() の失敗理由をPHPのエラーログに書く。
*/
add_action( 'wp_mail_failed', function ( $error ) {
$data = $error->get_error_data();
$to = isset( $data['to'] ) ? implode( ', ', (array) $data['to'] ) : '';
error_log( 'wp_mail failed: ' . $error->get_error_message() . ' / to: ' . $to );
} );
ログの出力先はPHPのエラーログです。WordPressのデバッグログに出したい場合は、wp-config.php の「編集が必要なのはここまでです」より上で次のように設定すると、wp-content/debug.log に書かれます。
<?php
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false ); // エラーを画面に出さない
手順1のコマンドをもう一度実行し、ログを確認します。
tail -n 20 wp-content/debug.log
調べ終わったら WP_DEBUG を false に戻し、debug.log を削除してください。debug.log はブラウザから直接開ける場所にあるため、残しておくと内部の情報が見られるおそれがあります。
エラーメッセージ別の原因と直し方
ログに出る主なメッセージと原因は次のとおりです(メッセージはPHPMailerの英語の文言)。
| ログのメッセージ | 主な原因 | 直し方 |
|---|---|---|
Could not instantiate mail function. |
サーバーの mail() が動かない(sendmail や Postfix が入っていない、mail() が無効にされている、Dockerなどの最小構成の環境) |
SMTP送信に切り替える。VPSならメール送信プログラムを設定する |
SMTP Error: Could not connect to SMTP host. |
SMTPのホスト名・ポートが違う、サーバーから外向きのSMTP接続が制限されている | 接続情報を確かめる。587番がだめなら465番を試し、サーバー会社の制限を確認する |
SMTP Error: Could not authenticate. |
SMTPのユーザー名・パスワードが違う | 認証情報を確かめる。Gmailならアプリ パスワードを使う |
Invalid address: で始まるもの |
送信元や宛先のメールアドレスの形式が正しくない | 送信元を wp_mail_from で正しいアドレスにする。宛先の入力値を確かめる |
mail() が使えない環境ではSMTPに切り替える
Could not instantiate mail function. が出る環境では、認証つきのSMTPサーバー(契約しているメールサーバー、メール配信サービスなど)経由で送るように切り替えます。WordPressは送信の直前に phpmailer_init アクションでPHPMailerのオブジェクトを渡すので、ここでSMTPを設定します。
<?php
/**
* Plugin Name: SMTP送信設定
* Description: wp-config.php の SMTP_* 定数を使って wp_mail() を SMTP 送信にする。
*/
add_action( 'phpmailer_init', function ( $phpmailer ) {
if ( ! defined( 'SMTP_HOST' ) ) {
return;
}
$phpmailer->isSMTP();
$phpmailer->Host = SMTP_HOST;
$phpmailer->Port = SMTP_PORT;
$phpmailer->SMTPSecure = SMTP_SECURE; // 587 は 'tls'、465 は 'ssl'
$phpmailer->SMTPAuth = true;
$phpmailer->Username = SMTP_USER;
$phpmailer->Password = SMTP_PASS;
} );
SMTP_HOST などの定数は、このコードのために決めた名前です(WordPress本体の設定ではありません)。パスワードを含むので、テーマのファイルではなく wp-config.php に define( 'SMTP_HOST', 'smtp.example.com' ); のように書きます。SMTP_PORT・SMTP_SECURE・SMTP_USER・SMTP_PASS も同じように定義してください。プラグイン「WP Mail SMTP」を使う方法や、Gmail・SendGrid・Amazon SESの接続情報はWordPressのメールをSMTP送信に変更する方法で説明しています。
送信元アドレスを自分のドメインのアドレスにする
送信元(From)を指定しないと、WordPressは wordpress@サイトのドメイン(先頭の www. は外す)を使います。このアドレスが実在しないと、SMTPサーバーに送信を拒否されたり、迷惑メールに分類されたりします。サイトのアドレスが localhost のような開発環境では、アドレスの形式が正しくないとして Invalid address: のエラーになることもあります。
送信元は wp_mail_from と wp_mail_from_name のフィルターで変えます。上の mu-plugin に追加できます。
<?php
add_filter( 'wp_mail_from', function ( $email ) {
return 'noreply@example.com'; // 自分のドメインの実在するアドレス
} );
add_filter( 'wp_mail_from_name', function ( $name ) {
return 'サイト名';
} );
true なのに届かないとき
wp_mail() が true を返すのに届かない場合は、WordPressより後ろで止まっています。次の順に確認します。
- 迷惑メールフォルダー:受信側で迷惑メールに分類されていないかを見ます
- サーバーのメールログ:
mail()で送っている場合は、サーバーのメール送信プログラムのログを見ます。Postfixなら、Debian・Ubuntuでは/var/log/mail.log、RHEL系では/var/log/maillogが一般的です。ファイルが無い環境ではjournalctl -u postfixで確認します。status=bouncedやstatus=deferredの行に、受信側が拒否した理由が書かれています - SMTPサービスの送信ログ:SMTP経由で送っている場合は、サービスの管理画面の送信ログを見ます
- 送信元ドメインの認証:送信元ドメインのSPF・DKIM・DMARCが、実際に送っているサーバーと合っているかを確認します。設定の確認方法はSPF・DKIM・DMARCの設定を確認する方法、WordPressからのメールが迷惑メールになるときの対策はWordPressのメールが迷惑メールになるときの対策を参照してください
別のプラグインが wp_mail() を置き換えていないか確かめる
wp_mail() は「プラガブル関数」と呼ばれ、プラグインが同じ名前の関数を先に定義すると、WordPress本体のものの代わりにそちらが使われます。メール関連のプラグインを複数入れていると、どの設定が効いているのか分からなくなります。次のコマンドで、実際に使われている wp_mail() がどのファイルにあるかを確認できます。
wp eval 'echo ( new ReflectionFunction( "wp_mail" ) )->getFileName(), PHP_EOL;'
wp-includes/pluggable.php 以外のファイルが表示された場合は、そのプラグインが送信を担当しています。そのプラグインの設定やログを確認するか、メール関連のプラグインを1つに絞ります。
注意点
- 古い解説にある
require_once ABSPATH . WPINC . '/class-phpmailer.php';は、WordPress 5.5 でPHPMailerの置き場所がwp-includes/PHPMailer/に変わってから非推奨です。PHPMailerを自分で作って送るのではなく、wp_mail()とphpmailer_initを使ってください initなどのフックで毎回メールを送るコードを試しに置くと、ページが表示されるたびにメールが送られます。テストは手順1の WP-CLI のコマンドで行います- SMTPのパスワードやAPIキーは
wp-config.phpに書き、テーマのファイルや公開リポジトリには書かないでください
まとめ
- まず
wp_mail()の戻り値を確かめ、WordPress側の失敗(false)か、その先の問題(true)かを分ける falseのときはwp_mail_failedでエラー文を記録し、メッセージから原因を絞るCould not instantiate mail function.ならSMTP送信に切り替え、送信元はwp_mail_fromで自分のドメインの実在するアドレスにするtrueなのに届かないときは、迷惑メールフォルダー、メールログ、SPF・DKIM・DMARCを確認する