Guide

WordPress wp_mail Not Working: Causes, Detection, and Fixes

The wp_mail() function is how WordPress sends every email. When it breaks, there’s no error page, no warning, and no notification. Here’s how to find and fix it.

How wp_mail() works

Every email WordPress sends - contact forms, password resets, WooCommerce orders, admin notifications - passes through wp_mail(). By default, it uses PHP’s built-in mail() function. SMTP plugins override this to route through external mail services.

The function returns true or false, but most themes and plugins ignore the return value. Even when wp_mail is not working, the form still submits and the user sees “Message sent.”

Common causes of wp_mail not working

  • SMTP plugin misconfiguration - wrong credentials, changed auth method after update, expired API key
  • PHP mail() disabled - hosting provider blocks the function for spam prevention
  • DNS records missing - no SPF, DKIM, or DMARC causes recipient servers to reject
  • Port blocked - firewall blocks outbound port 25, 465, or 587
  • Plugin conflict - two plugins hooking into wp_mail filter
  • Memory limit - email with large attachment exceeds PHP memory limit

How to debug wp_mail manually

1. Hook into wp_mail_failed

add_action('wp_mail_failed', function($error) {
    error_log('wp_mail failed: ' . $error->get_error_message());
});

This logs failures to debug.log. But you have to remember to check it.

2. Test with WP-CLI

wp eval 'var_dump(wp_mail("[email protected]", "Test", "Body"));'

Returns true or false. Tells you if wp_mail is working now, but not if it was working yesterday.

Monitoring wp_mail automatically

Logystera’s WordPress plugin hooks into wp_mail and captures every email attempt as a structured log event. The processor derives a success rate metric. When wp_mail stops working, you get an alert with the specific error - not a vague “something failed.”

What Logystera tracks:

  • Every wp_mail() call - success and failure
  • Error messages from the mail transport
  • Delivery rate as a metric - visible on dashboard
  • Alerts when failure rate crosses your threshold

Real example: SMTP auth silently changed

A WP Mail SMTP plugin auto-updated and changed the authentication method from LOGIN to PLAIN. The SMTP server rejected PLAIN auth. The plugin logged nothing visible. The contact form still showed “Thank you.” For 18 days, every email silently failed.

With Logystera, the first failed email would have triggered an alert: “wp_mail failed: SMTP Error: Authentication unsuccessful.”

Your logs already know

If wp_mail is not working on your site right now, the evidence is in your logs. The question is whether anyone is reading them.

Logystera doesn’t guess. It derives truth from logs.

{% set related = [{"href": "/guides/wordpress/emails-not-sending", "title": "WordPress Emails Not Sending"}, {"href": "/guides/wordpress/silent-php-errors", "title": "WordPress Silent PHP Errors"}, {"href": "/guides/wordpress/log-monitoring", "title": "WordPress Log Monitoring"}] %}

Related Logystera content

Frequently asked questions

What's the difference between wp_mail() and mail()?

wp_mail() is WordPress's wrapper around PHP's mail() function. It applies WordPress filters (wp_mail_from, wp_mail_content_type, etc.), handles plugin hooks, and is the function that SMTP plugins replace via the phpmailer_init action. mail() is the underlying PHP function — using it directly bypasses all WordPress mail logic and any SMTP plugin you have configured.

Can I test wp_mail() from the command line?

Yes: wp eval 'var_dump(wp_mail("[email protected]", "Test", "Hello"));' If it returns false, mail is broken. If it returns true and you don't receive it, the failure is downstream (SMTP, deliverability, inbox filtering).

Why does my SMTP plugin show emails as sent when they never arrive?

The plugin reports based on the SMTP server's acknowledgement — the message was accepted by the relay. From there it can still be rejected by the recipient's server or filtered to spam. SMTP plugins log "queued for delivery"; what you actually want to know is "delivered," which requires a deliverability webhook from your mail service.

Should every WordPress site use a transactional mail service?

For production, yes. Free Mailgun / Postmark / SendGrid / Resend tiers cover small site volumes. The deliverability difference between authenticated SMTP via a reputable service vs PHP's mail() is the difference between "arrives" and "spam folder."

See what's actually happening in your WordPress system

Connect your site. Logystera starts monitoring within minutes.

Logystera Logystera
Monitoring for WordPress and Drupal sites. Install a plugin or module to catch silent failures — cron stalls, failed emails, login attacks, PHP errors — before users report them.
Company
Copyright © 2026 Logystera. All rights reserved.