Muhammad Basim
Pin for WordPress Email: Why Your Site's Emails Never Arrive
WordPress

WordPress Email: Why Your Site’s Emails Never Arrive

Muhammad Basim
Muhammad Basim
·11 min read
Why Your Site's Emails Never Arrive

WordPress sends email in a way that fails modern authentication by default, and it reports success while doing it.

That combination is why this problem is so persistent. The site is not broken. Nothing is logged. wp_mail() returns true, the order is placed, the form says thank you — and the message never reaches an inbox.

Three separate problems get treated as one, which is why the standard fix works for some people and not others:

  • Transport — whether the message leaves your server at all
  • Authentication — whether the receiving server can verify you sent it
  • Reputation — whether your domain is trusted enough to be delivered

Installing an SMTP plugin fixes the first one. It does not necessarily fix the second and does nothing for the third. Most WordPress email guides stop after the first.


What WordPress actually does when it sends mail

Every email your site sends — password resets, order confirmations, form notifications, comment alerts — goes through one function: wp_mail().

By default, wp_mail() hands the message to PHP's mail() function, which hands it to whatever mail transfer agent the server runs, usually sendmail or a compatible substitute.

Three consequences follow from that, and all three cause problems.

It reports handoff, not delivery

wp_mail() returns true when the message was accepted for sending. Not when it arrived. Not when it was delivered. When it was handed over.

So a site whose email fails silently looks identical to a site whose email works. There is no error, no admin notice, no log entry. The failure is invisible from inside WordPress.

It sends from an address that usually does not exist

The default sender is wordpress@yourdomain.com, and on most sites no mailbox exists at that address.

Two things break. Bounce messages go nowhere, so you never learn a delivery failed. And a customer who replies to an order confirmation is writing to an address nobody reads.

It sends from your web server, which is not a mail server

This is the one that matters, and it is where authentication fails.

Your web host's server was set up to serve web pages. Its IP address is shared with other sites, some of which may be sending badly. It has no DKIM signing configured for your domain. And it is almost certainly not listed in your domain's SPF record — because you listed your email provider there, not your web host.


The authentication failure, precisely

This is the part that gets explained wrongly almost everywhere, and the detail is what makes it fixable.

SPF is not checked against the address your recipient sees. It is checked against the envelope sender — the Return-Path — which is a separate address the receiving server uses for bounces.

When PHP mail() sends from a shared host, the envelope sender is usually a server account — something like www-data@server47.hostingprovider.net. The From header your recipient sees still says orders@yourdomain.com.

So SPF is evaluated against the hosting provider's domain, and it may well pass. The hosting provider's own SPF record legitimately authorises their own servers.

And DMARC still fails, because DMARC requires alignment: the domain that passed SPF must match the domain in the From header. A passing SPF check on hostingprovider.net does not align with yourdomain.com, so as far as DMARC is concerned, nothing authenticated.

Which means a diagnostic that says "SPF: pass" can appear on a message that failed DMARC entirely. If you have ever checked a WordPress email header, seen a pass, and concluded authentication was fine, this is why it was not. How alignment actually works.

DKIM is usually absent entirely, because nothing on the web server is signing for your domain.

Result: no aligned SPF, no DKIM, DMARC fail. An unauthenticated message claiming to be from your domain — which is exactly the shape of a phishing attempt, and is treated accordingly.


Why this got worse, and when

Unauthenticated mail used to be delivered with a shrug. It is not any more.

Since February 2024, Gmail and Yahoo require every sender to authenticate with SPF or DKIM, regardless of volume. This is not a bulk-sender rule with a threshold underneath it — the basic authentication requirement applies to everyone, including a site sending four password resets a week.

Higher-volume senders face additional requirements — both SPF and DKIM, a DMARC record, one-click unsubscribe on marketing mail, and complaint rates kept low. The full requirements.

The practical effect on WordPress sites: mail that was landing in spam three years ago is now being rejected outright, and the site owner sees no difference between the two because neither produces an error.


What an SMTP plugin does, and what it does not

An SMTP plugin replaces the transport. Instead of handing the message to PHP mail(), wp_mail() connects to a real mail server with credentials and sends through it.

What that fixes:

  • Mail leaves through infrastructure built to send mail, from IPs with sending reputation
  • The provider signs with DKIM for your domain, if you completed domain authentication with them
  • Bounces are captured and reported
  • You get logs — a record of what was sent, accepted, bounced or rejected

What it does not fix on its own:

  • Authentication, unless you completed the provider's domain verification. Connecting a plugin with an API key and skipping the DNS records leaves you sending through better infrastructure and still failing alignment
  • Reputation. A new sending domain has none, and a domain with a bad history keeps it
  • A blocklisted domain. That is a separate process entirely
  • Content and list problems, if the site also sends marketing mail

The gap between "installed an SMTP plugin" and "email authenticates" is a set of DNS records, and it is where most WordPress sites stop. Setting it up properly.


Which service to send through

Three categories, and the right answer depends on volume and what else the domain sends.

Your existing mailbox provider's SMTP. Workable at low volume, and it is what many small sites use. Watch the sending limits, which are designed for a person typing emails rather than a server generating them.

A dedicated transactional service. Built for application email — password resets, receipts, notifications. Better deliverability, proper logs, bounce and complaint handling, and an API as well as SMTP. How to choose one.

Your marketing platform. Possible, and usually the wrong tool. Marketing platforms optimise for campaigns, and their transactional handling is secondary.

One structural point worth more than the choice itself: separate your transactional and marketing sending. A marketing campaign that generates complaints degrades the reputation your password resets depend on, and the reverse is also true. Using different subdomains for the two streams keeps one from taking the other down with it. Why streams matter.


Diagnosing it

In order, because each step rules out the one below.

1. Is WordPress calling wp_mail() at all? Install an email logging plugin. If nothing appears in the log, the problem is upstream — a form not submitting, an order status not changing, a notification disabled in settings. This step alone resolves a large share of "emails not sending" reports, and skipping it sends people to reconfigure DNS for a problem that was a checkbox.

2. Is it leaving the server? Send a test through the plugin's test function. A connection error is a transport problem: wrong port, wrong credentials, or the host blocking outbound SMTP. Port 25 is blocked by most shared hosts as an anti-abuse measure; use 587 with STARTTLS, or 465.

3. Is it authenticating? Send to an address you can inspect headers on, and read the Authentication-Results header. You are looking for DKIM pass and SPF pass on your own domain — not on your host's. Reading the results.

4. Where is it landing? Test to Gmail, Outlook and one other provider. Behaviour differs, and a message that reaches one and not another is a reputation signal rather than a configuration one.

5. Is your domain listed? Check your blocklist status. A listing explains total non-delivery when everything else looks correct.


The specific failures worth knowing

Sending as the visitor. Contact form plugins that set the From address to whoever filled in the form make your server send mail claiming to be from a domain you do not control. That fails the other domain's DMARC, and it is one of the most common causes of forms that silently stop working. Use your own domain in From and the visitor's address in Reply-To. The full fix.

Order emails that were never triggered. A WooCommerce order stuck at pending payment never reaches the status that fires the processing email. The email is not failing to send; it is not being asked to. Diagnosing order emails.

Recovery mode email. WordPress emails a recovery link when a fatal error occurs — through wp_mail(), on a site that is currently broken. The email that tells you how to fix the site is sent by the mechanism most likely to be failing. What to do instead.

A contact address on a domain you do not own. Setting the site's admin email to a Gmail address means notifications are sent from your domain to Gmail, and it also means your From and admin addresses disagree. Not fatal, and worth tidying.


What good looks like

A WordPress site whose email works reliably has all of this:

  • wp_mail() routed through a real mail service, not PHP mail()
  • Domain authentication completed at that service — the DKIM records published in DNS, and the service included in SPF
  • A DMARC record, so you can see what is failing. Setting one up
  • A From address that exists and is monitored
  • Reply-To set to a real inbox where a customer reply should go
  • Email logging enabled, so failures are visible
  • Transactional and marketing sending separated
  • A quarterly test to Gmail, Outlook and one other provider

Most of it is done once. The part that needs revisiting is the last item, because delivery degrades quietly and the first sign is usually a customer saying they never got their receipt.


Frequently asked questions

Why are my WordPress emails going to spam?
Most often because they are unauthenticated. WordPress sends through PHP mail() from your web server by default, which is not listed in your SPF record and is not signing with DKIM for your domain, so the message fails DMARC alignment. Routing through a real mail service and completing its domain verification resolves it.

Do I need an SMTP plugin?
Effectively yes for any site that depends on its email arriving. PHP mail() gives you no authentication, no logs and no bounce handling, and it reports success on messages that were never delivered. The plugin is the transport half; the DNS records are the other half.

Why does SPF pass but DMARC fail?
SPF is checked against the envelope sender, not the From address your recipient sees. On shared hosting the envelope sender is usually a hosting account, so SPF passes for the host's domain. DMARC requires the passing domain to match your From domain — and it does not, so DMARC fails despite the pass.

Does WordPress email need DKIM?
Since February 2024, Gmail and Yahoo require every sender to authenticate with SPF or DKIM regardless of volume. DKIM is the more reliable of the two because it survives forwarding, and any transactional service will sign for your domain once you publish their records.

Why do I get no error when WordPress email fails?
wp_mail() returns true when the message is handed off, not when it is delivered. Everything after the handoff — rejection, bouncing, silent discarding — happens outside WordPress and is never reported back. An email logging plugin is the only way to see it from inside the site.

Should transactional and marketing email use the same domain?
Better not to. Complaints from a marketing campaign degrade the reputation your password resets and order confirmations depend on. Separate subdomains for the two streams keep a bad campaign from taking your transactional mail down with it.

Which SMTP port should I use?
587 with STARTTLS, or 465 with implicit TLS. Port 25 is blocked outbound by most shared hosts as an anti-abuse measure, and a connection timeout on 25 is usually that block rather than a credentials problem.

The short version

  1. Install an email logging pluginInstall an email logging plugin and confirm WordPress is calling `wp_mail()` at all.
  2. Choose a sending serviceChoose a sending service u2014 your mailbox provider at low volume, or a transactional service.
  3. Install an SMTP pluginInstall an SMTP plugin and connect it with the service's credentials or API key.
  4. Complete domain authentication at the serviceComplete domain authentication at the service , publishing its DKIM records in your DNS.
  5. Add the service to your SPF recordAdd the service to your SPF record
  6. Set the From address to a real, monitored mailboxSet the From address to a real, monitored mailbox on your own domain.
  7. Set Reply-ToSet Reply-To to the inbox a customer reply should reach.
  8. Send a testSend a test and read the `Authentication-Results` header, checking that SPF and DKIM pass on your domain.
  9. Test delivery to Gmail, Outlook and one other providerTest delivery to Gmail, Outlook and one other provider
  10. Separate marketing sending onto a different subdomainSeparate marketing sending onto a different subdomain
  11. Re-test quarterlyRe-test quarterly , since delivery degrades quietly.

The WordPress Email Delivery Checklist

Stop your WordPress emails from failing silently. Get the complete setup guide.

Muhammad Basim

About the Author

Muhammad Basim

Digital Marketer & WordPress Developer

Muhammad Basim has worked in digital marketing since 2013, focused on email deliverability and AI-assisted content production. He is the author of The Email Deliverability Playbook and The Email Copywriting Playbook.

Related Articles

Newsletter

Free: The 60-Minute
Email Authentication Fix

A no-fluff checklist from the Deliverability Playbook. In one hour: set up SPF, DKIM & DMARC correctly, check your domain against blocklists, and pass Gmail & Yahoo's 2026 sender requirements.

No spam — that would be ironic. Unsubscribe anytime.