2026年5月29日
2026年5月29日
WordPressのメール送信が失敗する場合の解決方法
はじめに
WordPressでユーザー登録後の確認メールが届かない・Contact Form 7やWPFormsで送信してもメールが受信できない・パスワードリセットのメールが迷惑メールフォルダに入る・wp_mail()を使ったカスタムメール通知が動作しないといった問題は、共有ホスティングのSendmail設定・SPF/DKIM認証の未設定・from アドレスの不一致が原因でメールサーバーに拒否されていることがほとんどです。
症状・原因
- ユーザー登録・パスワードリセットのメールが届かない
- Contact Form 7の送信後「メールの送信に失敗しました」エラーが表示される
- メールが迷惑メールフォルダに振り分けられる
wp_mail_failedアクションが繰り返し発火してエラーログが膨大になる
解決手順
ステップ1:wp_mailの送信状況を診断する
# WP-CLIでテストメールを送信
wp eval "
\$result = wp_mail(
get_option('admin_email'),
'WP Mail Test ' . date('Y-m-d H:i:s'),
'This is a test email from WordPress.'
);
echo 'wp_mail result: ' . (\$result ? 'true' : 'false') . PHP_EOL;
"
# メール設定を確認
wp eval "
echo 'From: ' . get_option('admin_email') . PHP_EOL;
echo 'Blogname: ' . get_option('blogname') . PHP_EOL;
echo 'Siteurl: ' . get_option('siteurl') . PHP_EOL;
// PHPMailerの設定を確認
global \$phpmailer;
if (isset(\$phpmailer)) {
echo 'Mailer: ' . \$phpmailer->Mailer . PHP_EOL;
echo 'Host: ' . \$phpmailer->Host . PHP_EOL;
echo 'Port: ' . \$phpmailer->Port . PHP_EOL;
echo 'SMTPAuth: ' . (\$phpmailer->SMTPAuth ? 'yes' : 'no') . PHP_EOL;
}
"
ステップ2:メール送信エラーをログに記録する
// functions.php: メール送信の診断
// ① メール送信失敗を記録
add_action('wp_mail_failed', function(WP_Error $error): void {
$error_data = $error->get_error_data();
error_log(sprintf(
'[wp_mail_failed] Code: %s | Message: %s | To: %s | Subject: %s',
$error->get_error_code(),
$error->get_error_message(),
is_array($error_data['to'] ?? '') ? implode(',', $error_data['to']) : ($error_data['to'] ?? ''),
$error_data['subject'] ?? ''
));
});
// ② メール送信を記録(デバッグ用)
add_action('wp_mail', function(array $args): array {
if (defined('WP_DEBUG_LOG') && WP_DEBUG_LOG) {
error_log(sprintf(
'[wp_mail] To: %s | Subject: %s',
is_array($args['to']) ? implode(',', $args['to']) : $args['to'],
$args['subject']
));
}
return $args;
});
ステップ3:SMTPを設定して確実に送信する
// functions.php: PHPMailerをSMTPに設定
add_action('phpmailer_init', function(PHPMailer\PHPMailer\PHPMailer $phpmailer): void {
$phpmailer->isSMTP();
$phpmailer->Host = 'smtp.gmail.com'; // またはSMTPサーバーのホスト名
$phpmailer->SMTPAuth = true;
$phpmailer->Port = 587; // TLS: 587, SSL: 465
$phpmailer->SMTPSecure = PHPMailer\PHPMailer\PHPMailer::ENCRYPTION_STARTTLS;
$phpmailer->Username = defined('SMTP_USER') ? SMTP_USER : '';
$phpmailer->Password = defined('SMTP_PASS') ? SMTP_PASS : '';
// デバッグレベルの設定(本番は0、テストは2)
$phpmailer->SMTPDebug = defined('WP_DEBUG') && WP_DEBUG ? 2 : 0;
});
// wp-config.php: SMTP認証情報を安全に管理
define('SMTP_USER', 'your-email@gmail.com');
define('SMTP_PASS', 'your-app-password'); // Gmailはアプリパスワードを使用
// 送信元アドレスを設定
define('WP_MAIL_FROM', 'noreply@your-domain.com');
define('WP_MAIL_FROM_NAME', 'Your Site Name');
// functions.php: 送信元アドレスを統一
add_filter('wp_mail_from', function(string $email): string {
return defined('WP_MAIL_FROM') ? WP_MAIL_FROM : $email;
});
add_filter('wp_mail_from_name', function(string $name): string {
return defined('WP_MAIL_FROM_NAME') ? WP_MAIL_FROM_NAME : $name;
});
ステップ4:メールの到達率を改善する
// functions.php: メール到達率向上設定
// ① HTMLメールのContent-Typeを設定
add_filter('wp_mail_content_type', function(): string {
return 'text/html; charset=UTF-8';
});
// ② メールヘッダーを追加してスパム判定を回避
add_filter('wp_mail', function(array $args): array {
$site_domain = parse_url(home_url(), PHP_URL_HOST);
$additional_headers = [
'X-Mailer: WordPress/' . get_bloginfo('version'),
'X-Site: ' . $site_domain,
'Reply-To: ' . get_option('admin_email'),
];
if (empty($args['headers'])) {
$args['headers'] = $additional_headers;
} elseif (is_array($args['headers'])) {
$args['headers'] = array_merge($args['headers'], $additional_headers);
}
return $args;
});
// ③ 送信失敗時に再試行
add_action('wp_mail_failed', function(WP_Error $error): void {
$error_data = $error->get_error_data();
if (!isset($error_data['to'])) return;
// 5分後に再送信をスケジュール
wp_schedule_single_event(
time() + 300,
'retry_failed_mail',
[$error_data]
);
});
add_action('retry_failed_mail', function(array $mail_data): void {
wp_mail(
$mail_data['to'],
'[再送] ' . ($mail_data['subject'] ?? ''),
$mail_data['message'] ?? '',
$mail_data['headers'] ?? []
);
error_log('[wp_mail] Retry sent to: ' . (is_array($mail_data['to']) ? implode(',', $mail_data['to']) : $mail_data['to']));
});
ステップ5:メール送信ログと監視を設定する
// functions.php: メール送信ログ
// ① 送信したメールをデータベースに記録
add_action('wp_mail', function(array $args): array {
global $wpdb;
$table = $wpdb->prefix . 'mail_log';
// テーブルが存在しない場合は作成
if ($wpdb->get_var("SHOW TABLES LIKE '$table'") !== $table) {
$wpdb->query(
"CREATE TABLE $table (
id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
sent_at datetime NOT NULL,
to_address text NOT NULL,
subject varchar(255) NOT NULL,
status varchar(20) DEFAULT 'pending',
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"
);
}
$wpdb->insert($table, [
'sent_at' => current_time('mysql'),
'to_address' => is_array($args['to']) ? implode(',', $args['to']) : $args['to'],
'subject' => $args['subject'],
'status' => 'sent',
]);
return $args;
});
// ② 1日のメール送信数が制限を超えた場合に警告
add_action('wp_mail', function(array $args): array {
$today_count = (int) get_transient('daily_mail_count');
$today_count++;
set_transient('daily_mail_count', $today_count, DAY_IN_SECONDS);
if ($today_count > 500) {
error_log('[wp_mail] Warning: Daily mail limit approaching (' . $today_count . ')');
}
return $args;
});
注意事項
- Gmailを使用する場合は、「通常のパスワード」ではなく「アプリパスワード」を使用してください。Googleアカウントの2段階認証を有効にした後、セキュリティ設定からアプリパスワードを生成できます
- SPF・DKIM・DMARCを設定していないドメインからのメールは迷惑メールとして扱われる可能性が高いです。DNSレコードにSPFレコード(
v=spf1 include:_spf.google.com ~allなど)を追加し、送信ドメインを正しく認証してください - 大量のメール送信(ニュースレターなど)にはSendGrid・Amazon SES・Mailgunなどの専用メール配信サービスの使用を推奨します。WordPressの
wp_mail()は大量送信向けに設計されておらず、IPアドレスのブラックリスト登録リスクがあります
まとめ
WordPressメール送信修復は①wp evalでwp_mailテスト・PHPMailerの現在のMailer/Host/Portを確認、②wp_mail_failedフックでエラーコード・宛先・件名をログ記録・デバッグ用送信ログ設定、③phpmailer_initフックでSMTP接続設定・wp-config.phpにSMTP認証情報を定数で管理、④wp_mail_from/wp_mail_from_nameフィルターで送信元統一・X-Mailerヘッダー追加・送信失敗時5分後再試行スケジュール、⑤送信メールをDBログテーブルに記録・1日500件超で警告ログ出力する手順で解決します。