The Problem
WordPress's wp_mail() function fails to send emails because the SMTP server requires authentication and the default PHP mail() function does not support SMTP auth. This affects password resets, order confirmations, and contact forms.
Symptoms
- Password reset emails never arrive
- WooCommerce order confirmations not sent
- Contact form submissions do not send notifications
- "SMTP Error: Could not authenticate" in logs
- Works with some email providers but not others
Real Error Message
SMTP Error: Could not authenticate.
SMTP server response: 535 5.7.8 Username and Password not accepted.
Learn more at https://support.google.com/mail/?p=BadCredentialsCommon Causes
Cause 1: Using Default PHP mail() Without SMTP
PHP's mail() function does not support SMTP authentication. Most email providers (Gmail, SendGrid, etc.) require authentication.
Cause 2: Wrong SMTP Port or Encryption
Port 25: Often blocked by hosting providers
Port 587: Requires STARTTLS
Port 465: Requires SSL/TLSHow to Fix It
Fix 1: Configure SMTP with WP Mail SMTP Plugin
Install WP Mail SMTP and configure:
SMTP Host: smtp.gmail.com
SMTP Port: 587
Encryption: TLS
Authentication: Yes
Username: your-email@gmail.com
Password: Your App Password (not regular password!)Fix 2: Generate App Password for Gmail
# Gmail no longer allows regular passwords for SMTP
# Generate an App Password:
# 1. Go to Google Account -> Security
# 2. Enable 2-Step Verification
# 3. Go to App Passwords
# 4. Generate password for "Mail"
# 5. Use the 16-character app passwordFix 3: Configure via wp-config.php
// wp-config.php (for WP Mail SMTP plugin)
define('WPMS_ON', true);
define('WPMS_MAILER', 'smtp');
define('WPMS_SET_RETURN_PATH', 'true');
define('WPMS_SMTP_HOST', 'smtp.sendgrid.net');
define('WPMS_SMTP_PORT', 587);
define('WPMS_SSL', 'tls');
define('WPMS_SMTP_AUTH', true);
define('WPMS_SMTP_USER', 'apikey');
define('WPMS_SMTP_PASS', 'your-sendgrid-api-key');
define('WPMS_SMTP_AUTOTLS', true);Fix 4: Test SMTP Connection
```bash # Test SMTP from command line openssl s_client -connect smtp.gmail.com:587 -starttls smtp
# Or use swaks swaks --to test@example.com --from your@gmail.com \ --server smtp.gmail.com:587 --auth \ --auth-user your@gmail.com --auth-password your-app-password \ --tls ```
Fix 5: Send a Test Email
```php // Test wp_mail $result = wp_mail( 'test@example.com', 'Test Email', 'This is a test email from WordPress.', ['Content-Type: text/html; charset=UTF-8'] );
var_dump($result); // true = sent, false = failed ```
Fix 6: Check PHPMailer Error Log
// Add to functions.php for debugging
add_action('phpmailer_init', function($phpmailer) {
$phpmailer->SMTPDebug = 2; // Enable debug output
$phpmailer->Debugoutput = 'error_log'; // Log to debug.log
});Fix 7: Use Transactional Email Service
For reliable delivery, use a transactional email service:
- SendGrid: 100 free emails/day
- Mailgun: 5,000 free emails/month
- Postmark: Reliable delivery tracking
- Amazon SES: Very low cost per email