Why are my WordPress emails not being delivered?

WordPress email fails for four distinct reasons, and the fixes are different for each. Before installing a plugin or changing a setting, sort which failure mode you’re in. The diagnostic below takes about five minutes and rules out three of the four causes so you know which one to fix.

The four causes, in the order they should be ruled out:

  1. wp_mail() cannot send at all. PHP’s mail() function is disabled on the host, no SMTP plugin is configured, and mail leaves WordPress with nowhere to go.
  2. Mail sends but authenticates against the wrong domain. The SMTP plugin is configured, but the From: address doesn’t align with the DNS records, and Gmail treats every message as spam or rejects it outright.
  3. Mail sends and authenticates but goes to Junk at Microsoft 365 or Yahoo. The sending IP or domain has poor reputation, or the message has content-based spam signals.
  4. Mail sends to some recipients but not others. A WooCommerce, contact form, or membership plugin is overriding the From: header per-message, and only some code paths are affected.

Step 1: install a logging plugin and confirm what’s happening

Install Check & Log Email or Log Emails before touching any other setting. Both plugins hook into wp_mail() and record every send attempt: the timestamp, the To: and From: addresses, the subject, and whether the mailer returned success or failure.

Trigger a password reset for a test account from /wp-login.php?action=lostpassword and check the log:

  • No log entry. wp_mail() was never called. A security plugin is throttling password resets (Wordfence, Limit Login Attempts Reloaded, Solid Security, WP Cerber all do this). Test with a different sender (a contact form submission, a Users > Add New confirmation email) to confirm.
  • Log entry with status “failure.” The mailer rejected the message. You’re in cause 1 (default mail() unreachable) or a credential/host mismatch in an installed SMTP plugin.
  • Log entry with status “success” but no email arrives. WordPress handed the message off cleanly and the mailer accepted it. You’re in cause 2, 3, or 4.

wp_mail() returns true when the mailer accepts the handoff, not when the mail is delivered. Without a logging plugin, a successful handoff and a delivery failure look identical from the WordPress side. Install one first; it removes the ambiguity.

Cause 1: wp_mail() cannot send at all

The most common failure on a fresh WordPress install. PHP’s mail() function is disabled by security policy on Kinsta, WP Engine, Flywheel, and Pressable. Shared hosts (SiteGround, GoDaddy, Bluehost) leave it available but throttle it heavily and don’t publish SPF or DKIM on the customer’s behalf. In either case, WordPress calls wp_mail(), PHPMailer calls PHP’s mail(), and the message either fails immediately or leaves the server with no authentication and gets rejected downstream.

The fix: an SMTP plugin paired with a transactional email provider. FluentSMTP free tier plus SMTP2GO free tier (1,000 messages per month) covers a small site with zero recurring cost. See What is the best way to set up email on WordPress? for the full setup.

Cause 2: mail authenticates against the wrong domain

This is the failure mode that produces “WooCommerce emails arrive, but password resets go to spam” and “some emails arrive at Gmail, others don’t.” The site has an SMTP plugin configured and the message leaves WordPress successfully, but the From: address doesn’t align with the DNS records the plugin’s provider published.

WordPress’s default From: header is constructed as wordpress@<network_home_url minus scheme minus www>. On a site whose home URL is https://store.example.com, the default becomes [email protected] (a subdomain). Whether SPF and DKIM published for example.com cover that subdomain under DMARC alignment depends on how strictly each mailbox provider enforces the check, and Microsoft 365 in particular treats bare-hostname or unexpected-subdomain From addresses as suspicious.

The fix: set an explicit From: address on the organisational domain ([email protected], [email protected]) in the SMTP plugin. Enable “Force From Email” so that WooCommerce, membership plugins, and contact form plugins can’t override it per-message. See Users not receiving password reset emails in WordPress for the specific case where this fails and the exact fix, and Change WordPress’s default email sender details for the mechanical setup.

Cause 3: authenticated mail lands in Junk

The mail authenticates, arrives, and lands in the recipient’s spam folder rather than the inbox. Two subcauses:

Provider IP reputation. If you’re on a shared-IP tier of a transactional provider, the IP’s reputation depends on every other sender using it. Reputable providers (Postmark, SMTP2GO) actively kick low-reputation senders off shared IPs; less reputable providers (Sendinblue’s early free tier, cheap bulk relays) leave the pool contaminated. If mail is authenticating cleanly but landing in Junk consistently, check the sender score at mail-tester.com. A score below 8/10 with all authentication passing usually points at IP reputation.

Content signals. Aggressive marketing language, all-caps subject lines, unusual link ratios, missing plain-text version, or an unsubscribe link that violates List-Unsubscribe conventions. Transactional mail (password resets, order confirmations) rarely hits content-based spam filters. Newsletter-style mail regularly does; see WordPress email test suite for the checks that surface content issues before you send.

Cause 4: mail sends to some recipients but not others

WooCommerce, membership plugins, and contact form plugins can each set their own From: header at the message level. A site can have “Force From Email” enabled in the SMTP plugin and still see WooCommerce reset emails fail because WooCommerce has its own From: field at WooCommerce > Settings > Emails that takes precedence.

The diagnostic: check the log entries for the specific message type that’s failing. If the From: address on the failing message is different from the From: on messages that succeed, a plugin is overriding it. Find and align the setting.

See Form not sending mail to Gmail (but sending to Office 365) for a specific instance of this: mail arrives at Microsoft 365 (which downgrades failures to Junk) but is rejected outright at Gmail (which enforces authentication strictly).

The single fix that resolves the largest fraction

If the site is on a modern host, already has an SMTP plugin, has SPF and DKIM published for the domain, and is still seeing deliverability problems: set an explicit From: address on the organisational domain in the SMTP plugin’s “From Email” field, and enable “Force From Email.” This one change fixes more WordPress deliverability failures than any other single setting. The remaining causes (Junk at destination, per-plugin override) affect narrower subsets and need the diagnostic above to identify.

For the deeper walk-through: Troubleshoot WordPress email.