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件超で警告ログ出力する手順で解決します。

お気軽にご相談ください

お見積りへ お問い合わせへ