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

bash
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=BadCredentials

Common 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

bash
Port 25: Often blocked by hosting providers
Port 587: Requires STARTTLS
Port 465: Requires SSL/TLS

How to Fix It

Fix 1: Configure SMTP with WP Mail SMTP Plugin

Install WP Mail SMTP and configure:

bash
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

bash
# 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 password

Fix 3: Configure via wp-config.php

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

php
// 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