Skip to content

How to fix WordPress not sending email

WordPress hands every email to the mail program on its own server. Many hosts restrict that program or do not provide one, and mail sent that way is often treated as spam. A two-minute test shows which problem you have. The lasting fix is a mail service that vouches for your domain.

By
WP Ministry
Published
Tested on
WordPress 7.1.3, PHP 8.3.35

In short

  • WordPress does not deliver email. It hands each message to the server, and many servers cannot send it or are not allowed to.
  • Use "Lost your password?" on the login screen as a test. It says outright when a message could not be handed over.
  • The lasting fix is a mail service that sends from your own domain, with SPF, DKIM and DMARC records in place.
  • A message that failed is not sent again. Fix the cause, then follow up by hand.

WordPress does not deliver email itself. It hands each message to the mail program on the server it runs on, and leaves the rest to that program. Password resets, form messages, order receipts and the recovery link WordPress sends when a site has a critical error all go the same way.

Two things go wrong. On many hosts the mail program is missing, limited or switched off, so the message never leaves. And where it does leave, it comes from a web server that nothing vouches for, so the receiving side files it as spam or refuses it.

The site itself is working, and nothing on it is lost. A message that failed is not sent again, though. WordPress keeps no queue.

Find out which problem you have

Open your login screen in a private window and follow "Lost your password?". Enter your username and press Get New Password. The message goes to the address in that user's profile.

  • "The email could not be sent. Your site may not be correctly configured to send emails." WordPress could not hand the message over. Use the first fix.
  • "Check your email for the confirmation link, then visit the login page." The server accepted the message. Give it a few minutes, then look in your inbox and your spam folder. If it is in spam, or nowhere, use the first two fixes. If it is in your inbox, WordPress can send, and the last fix is the one to look at.

With WP-CLI, using your own address in place of you@example.com:

bash
wp eval 'add_action( "wp_mail_failed", function ( $error ) { echo $error->get_error_message(), "\n"; } ); var_dump( wp_mail( "you@example.com", "Test from WordPress", "If you can read this, WordPress can send email." ) );'

bool(false) means the hand-over failed, and the line above it says why. "Could not instantiate mail function." means the server's mail program refused the message or is not there. bool(true) means the server accepted the message. It does not mean the message arrived.

If it is order emails that are missing, check first that the orders themselves are in your shop's order list. If they are not, the problem is the checkout and not email: see WooCommerce checkout not working.

Where it goes wrong

A page request passes through each of these in turn. This one comes from the hosting account.

  1. Browser
  2. DNS
  3. HTTPS
  4. CDN or firewall
  5. Web server (this error comes from here)
  6. PHP
  7. WordPress
  8. Database and files

What causes it

  • The server cannot send mail, or the host restricts it

    Common

    WordPress hands every message to the mail program on its own server. Many hosts limit that program, switch it off or never installed one, and WordPress has no other way out.

    Fix: Send through a mail service

  • The mail is sent, but nothing vouches for it

    Common

    A message that claims to come from your domain, sent by a web server your domain's DNS records do not name, looks forged. Receiving servers put it in spam or refuse it.

    Fix: Send through a mail service, or Add the DNS records that vouch for your mail

  • WordPress is sending to an address nobody reads

    Sometimes

    WordPress's own notices go to the administration email address, which is often still the address of whoever built the site. Form and shop plugins keep recipient settings of their own.

    Fix: Check where WordPress is sending

How to fix it

Send through a mail service

  • Takes care
  • Low risk
  • About 30 minutes

A mail service takes each message from WordPress over SMTP, with a username and a password, and delivers it from servers that are set up for sending mail.

  1. Step 1: Choose a service

    Two kinds will do: the provider that already runs the mailboxes at your domain, or a transactional mail service, which is built for the messages a website sends. Look for three things. It lets you send from an address at your own domain. It gives you SPF and DKIM records for that domain. It shows a log of what it delivered.

  2. Step 2: Collect its SMTP details

    You need a host name, a port, a username and a password. The port is commonly 587.

  3. Step 3: Connect WordPress to it

    Install an SMTP plugin: one that asks for those four details, sends a test message and keeps a log of failures. Enter the details, and set the "from" address to one at your own domain.

  4. Step 4: Run the test again

    Repeat the test at the top of this page. If the WP-CLI test now says "SMTP Error: Could not connect to SMTP host.", the server cannot reach the service. Check the host name and port, then ask your host whether it allows outgoing connections on that port.

To do it without a plugin, create a file in wp-content/mu-plugins/, making that folder if it is not there. Use your service's details in place of the stand-ins.

wp-content/mu-plugins/smtp.php
<?php
add_action( 'phpmailer_init', function ( $phpmailer ) {
	$phpmailer->isSMTP();
	$phpmailer->Host       = 'smtp.example.com';
	$phpmailer->Port       = 587;
	$phpmailer->SMTPSecure = 'tls';
	$phpmailer->SMTPAuth   = true;
	$phpmailer->Username   = 'your-smtp-username';
	$phpmailer->Password   = 'your-smtp-password';
} );
add_filter( 'wp_mail_from', function () {
	return 'website@example.com';
} );

If your service uses port 465, set SMTPSecure to 'ssl'. The file holds a password, so leave it out of any copy of the site you share.

To undo it: Deactivate the SMTP plugin, or delete the file you added.

Add the DNS records that vouch for your mail

  • Takes care
  • Low risk
  • About 30 minutes

Receiving servers check that a message claiming to come from your domain was sent by a server your domain names. Three kinds of DNS record carry that information: SPF, DKIM and DMARC.

  1. Step 1: Send from an address at your own domain

    Not from a free webmail address, and not from the address a visitor typed into a form. A message "from" a domain your mail service does not send for fails the checks. In a form plugin, set the sender to your own address and put the visitor's address in the reply-to field.

  2. Step 2: Add the SPF and DKIM records your mail service gives you

    Add them wherever your domain's DNS is managed. A domain may have only one SPF record. If you already have one, add the service's part to it. Do not create a second.

  3. Step 3: Add a DMARC record

    It is a TXT record named _dmarc at your domain. This one asks receivers to report on your mail without changing how they treat it, which is the place to start. Use your own address in it.

    text
    v=DMARC1; p=none; rua=mailto:you@example.com
  4. Step 4: Check the result

    Send the test to a mailbox of your own. Open the message's full headers and find the line that begins Authentication-Results. It should say spf=pass, dkim=pass and dmarc=pass. New DNS records can take a few hours to be seen everywhere.

Check where WordPress is sending

  • Easy
  • No risk
  • About 5 minutes
  • Steps tested on WordPress 7.1.3

WordPress sends its own notices, such as a new user or a comment that awaits moderation, to one address: the administration email address.

  1. Step 1: Go to Settings, then General

    Look at "Administration Email Address".

  2. Step 2: Change it if it is not yours

    WordPress emails a link to the new address, and says under the box: "The new address will not become active until confirmed." So mail has to be working before this change can take effect. If the link never arrives, do the first fix and come back, or use the command below.

  3. Step 3: Check the other places an address is kept

    Each user has an address of their own, under Users, then Profile. Password resets go there. Form and shop plugins keep their own lists of who is told about a message or an order, in each one's notification settings.

With WP-CLI the change takes effect at once, with no link to confirm. Use your own address in place of you@example.com.

bash
wp option update admin_email 'you@example.com'

WordPress sends the old address a notice with the subject "Admin Email Changed", after the site's name.

To undo it: Set the address back to what it was.

When to get help

If mail goes through a mail service, the SPF, DKIM and DMARC checks all pass and messages still go missing, the answer is in the service's delivery log, which shows whether the receiving server accepted, delayed or refused each one. Reading that log against your DNS records is a job for someone who does it often.

Common questions

WordPress said the message was sent. Why did it not arrive?

"Sent" means the server's mail program accepted the message. What happens after that is out of WordPress's sight, and WordPress keeps no record of it. A mail service's delivery log is how you find out.

Will the emails that failed be sent once this is fixed?

No. WordPress does not keep a message it could not send. Orders are still in your shop's order list, and some form plugins keep each entry in the dashboard. Contact those people yourself.

Why do emails reach some people and not others?

Each mailbox provider decides for itself. Mail with nothing to vouch for it can be accepted by one provider, put in spam by another and refused by a third. Once SPF, DKIM and DMARC pass, most of that difference goes away.

My host says mail from the server works. Do I still need a mail service?

Run the check at the end of the second fix on a message sent the host's way. If it shows spf=pass, dkim=pass and dmarc=pass and the message is in your inbox, you do not. If any of the three is missing, a mail service is the simpler way to get them.

More on this subject

Would you rather we fixed it?

Quick Fix is $49. One issue, one site, up to about an hour. No fix, no fee. 30-day warranty. It starts with a free diagnosis.