# Fix WordPress Email Not Sending
WordPress sends emails for password resets, new user registrations, comment notifications, and plugin-generated emails like contact forms. When emails aren't sending, users can't reset passwords, admins miss notifications, and contact forms silently fail.
WordPress uses PHP's built-in mail function by default, which is notoriously unreliable. Most email issues stem from server mail configuration, spam filtering, or missing SMTP setup.
Quick Diagnosis
Test Email Sending
```bash # Test wp_mail function wp eval 'wp_mail("your-email@example.com", "Test Email", "This is a test email from WordPress"); echo "Email sent\n";'
# Check if PHP mail works wp eval '$result = mail("your-email@example.com", "PHP Mail Test", "Test message"); echo $result ? "Sent\n" : "Failed\n";' ```
Check Mail Logs
```bash # Server mail log (requires access) tail -100 /var/log/mail.log tail -100 /var/log/maillog
# Check sendmail/postfix status systemctl status postfix systemctl status sendmail ```
Check WordPress Mail Configuration
```bash # Look for mail-related constants grep -i "smtp|mail|phpmailer" wp-config.php
# Check for SMTP plugins wp plugin list --fields=name,status | grep -i "smtp|mail|wp-mail" ```
Why WordPress Emails Fail
1. PHP Mail Disabled
Many shared hosts disable PHP's mail() function.
# Check if mail function exists
wp eval 'echo function_exists("mail") ? "mail() available\n" : "mail() disabled\n";'Solution: Use SMTP plugin
wp plugin install wp-mail-smtp --activate2. No SMTP Server
WordPress needs an SMTP server to send emails reliably.
Install WP Mail SMTP plugin:
wp plugin install wp-mail-smtp --activateConfigure with your email provider:
Gmail SMTP: - Host: smtp.gmail.com - Port: 587 (TLS) or 465 (SSL) - Encryption: TLS - Authentication: Login - Username: your-email@gmail.com - Password: App password (not your Gmail password)
- 1.Create Gmail App Password:
- 2.Google Account > Security > 2-Step Verification
- 3.App passwords > Create new
- 4.Use that password in WP Mail SMTP
Other providers:
| Provider | SMTP Host | Port |
|---|---|---|
| Outlook | smtp.office365.com | 587 |
| Yahoo | smtp.mail.yahoo.com | 587 |
| SendGrid | smtp.sendgrid.net | 587 |
| Mailgun | smtp.mailgun.org | 587 |
| Amazon SES | email-smtp.region.amazonaws.com | 587 |
3. Emails Marked as Spam
Emails send but land in spam folders.
Fix email headers:
```php // Improve email headers add_filter('wp_mail_from', function($email) { return 'noreply@yourdomain.com'; });
add_filter('wp_mail_from_name', function($name) { return 'Your Site Name'; }); ```
Set up SPF/DKIM records:
Add to your DNS:
``` # SPF record TXT @ "v=spf1 include:_spf.google.com ~all"
# DKIM (via SMTP provider) # Check your email provider for DKIM setup ```
4. Missing Return Path
Emails have wrong return path causing delivery failure.
// Fix return path
add_filter('wp_mail', function($args) {
$args['headers'] .= "\nReturn-Path: noreply@yourdomain.com";
return $args;
});5. Content-Type Issues
HTML emails sent as plain text or vice versa.
```php // Force HTML content type add_filter('wp_mail_content_type', function() { return 'text/html'; });
// Or send multipart wp_mail($to, $subject, $message, array('Content-Type: text/html; charset=UTF-8')); ```
Fix Common Email Problems
Password Reset Emails Not Sending
Users can't reset passwords.
Check password reset hook:
// Debug password reset emails
add_action('retrieve_password_message', function($message, $key, $user_login, $user_data) {
error_log("Password reset email for: $user_login");
return $message;
}, 10, 4);Force password reset email:
```bash # Generate reset link wp eval ' $user = get_user_by("email", "user@example.com"); $key = get_password_reset_key($user); echo wp_login_url() . "?action=rp&key=$key&login=" . $user->user_login; '
# Send manually wp user reset-password user@example.com --send-email ```
Contact Form 7 Not Sending
Contact forms silently fail.
Check CF7 configuration:
```bash wp plugin list --name=contact-form-7 --fields=name,status,version
# Check CF7 submissions wp eval ' $submissions = WPCF7_Submission::get_instance(); if ($submissions) { echo "Status: " . $submissions->get_status() . "\n"; echo "Response: " . $submissions->get_response() . "\n"; } ' ```
Enable CF7 debugging:
// In wp-config.php
define('WPCF7_DEBUG', true);Check spam folder:
CF7 emails often land in spam. Check your spam folder.
Use SMTP:
```bash # Install SMTP plugin wp plugin install wp-mail-smtp --activate
# Configure to fix CF7 emails ```
WooCommerce Emails Not Sending
Order emails fail.
Check WooCommerce email settings:
```bash wp option get woocommerce_email_from_address wp option get woocommerce_email_from_name
# Check email template status wp wc tool list | grep -i email ```
Enable WooCommerce email logging:
wp option update woocommerce_email_logging_enabled 'yes'
wp wc log list --user=1 | grep emailTest WooCommerce emails:
# Trigger test email
wp wc tool run send_test_email --user=1Plugin-Specific Email Issues
WPForms:
```bash wp plugin list --name=wpforms --fields=name,status
# Check WPForms entries wp eval ' $entries = wpforms()->entry->get_all(); foreach ($entries as $entry) { echo $entry->id . ": " . $entry->status . "\n"; } ' ```
Ninja Forms:
```bash wp plugin list --name=ninja-forms --fields=name,status
# Check action logs wp eval 'NF_Display_Render::get_actions();' ```
Configure SMTP via WP-CLI
```bash # Install WP Mail SMTP wp plugin install wp-mail-smtp --activate
# Set SMTP settings wp option update wp_mail_smtp '{"mail":{"from_email":"noreply@yourdomain.com","from_name":"Your Site","mailer":"smtp"},"smtp":{"host":"smtp.gmail.com","port":"587","encryption":"tls","user":"your-email@gmail.com","pass":"your-app-password"}}' --format=json
# Test SMTP connection wp eval ' $mailer = new WP_Mail_SMTP(); $result = $mailer->test_connection(); echo $result ? "SMTP connected\n" : "SMTP failed\n"; ' ```
Alternative: Use Transactional Email Service
For reliable delivery, use a transactional email service:
SendGrid
```bash wp plugin install sendgrid-email-delivery-simplified --activate
# Configure wp option update sendgrid_api_key 'SG.your-api-key' ```
Mailgun
```bash wp plugin install mailgun --activate
wp option update mailgun_api_key 'key-your-key' wp option update mailgun_domain 'mg.yourdomain.com' ```
Amazon SES
```bash wp plugin install aws-ses-wp-mail --activate
wp option update aws_ses_access_key 'your-access-key' wp option update aws_ses_secret_key 'your-secret-key' wp option update aws_ses_region 'us-east-1' ```
Debug Email Sending
Enable PHPMailer Debug
```php // In functions.php or must-use plugin add_action('phpmailer_init', function($phpmailer) { $phpmailer->SMTPDebug = 2; // 2 = detailed debug $phpmailer->Debugoutput = 'error_log'; });
// Watch debug output // In wp-content/debug.log ```
Log All Emails
```php // Log email attempts add_action('wp_mail_failed', function($error) { error_log('Email failed: ' . $error->get_error_message()); });
add_action('wp_mail_succeeded', function($email_data) { error_log('Email sent to: ' . implode(',', $email_data['to'])); }); ```
Test Email with Raw PHPMailer
wp eval '
global $phpmailer;
$phpmailer = new PHPMailer\PHPMailer\PHPMailer(true);
try {
$phpmailer->setFrom("noreply@yourdomain.com", "Test");
$phpmailer->addAddress("your-email@example.com");
$phpmailer->Subject = "PHPMailer Test";
$phpmailer->Body = "Test message";
$phpmailer->isSMTP();
$phpmailer->Host = "smtp.gmail.com";
$phpmailer->SMTPAuth = true;
$phpmailer->Username = "your-email@gmail.com";
$phpmailer->Password = "your-app-password";
$phpmailer->SMTPSecure = "tls";
$phpmailer->Port = 587;
$phpmailer->send();
echo "Sent\n";
} catch (Exception $e) {
echo "Failed: " . $e->getMessage() . "\n";
}
'Fix Server-Level Mail
Check Sendmail/Postfix
```bash # Check if mail server installed which sendmail which postfix
# Install postfix if missing sudo apt install postfix
# Configure postfix sudo dpkg-reconfigure postfix ```
Check PHP Mail Configuration
```bash # Check sendmail_path in PHP php -i | grep sendmail_path
# May show: sendmail_path = /usr/sbin/sendmail -t -i ```
Test Direct Mail Command
```bash # Test sendmail directly echo "Subject: Test Email From: noreply@yourdomain.com To: your-email@example.com
Test message" | sendmail -t
# Check mail queue mailq ```
Verification
After fixes:
```bash # Test WordPress email wp eval 'wp_mail("test@example.com", "Test Subject", "Test message"); echo "Attempted\n";'
# Check logs tail -20 wp-content/debug.log | grep -i mail
# Check mail queue (if using server mail) mailq
# Test contact form submission manually wp eval ' if (class_exists("WPCF7_Submission")) { $contact_form = wpcf7_get_contact_form_by_title("Contact form 1"); echo "CF7 form exists: " . ($contact_form ? "yes" : "no") . "\n"; } ' ```
Quick Reference
| Issue | Cause | Fix |
|---|---|---|
| No emails sent | PHP mail disabled | Use SMTP plugin |
| Emails in spam | Missing SPF/DKIM | Add DNS records |
| Password reset fails | Email not delivered | SMTP + check spam |
| Contact form silent | Missing SMTP | Configure WP Mail SMTP |
| WooCommerce orders | Email settings | Check WC email config |
| HTML stripped | Content-type wrong | Set HTML header |
WordPress email issues almost always require SMTP. PHP mail() is unreliable on most servers. Install WP Mail SMTP, configure with your email provider, and verify with test emails.