WordPress Not Sending Emails? How to Fix It for Good.

Contact form messages that never arrive, password reset emails that don’t show up, WooCommerce order notifications going missing: email problems are among the most common WordPress complaints, and they’re easy to miss because nothing on the site looks broken.

There are really only two ways WordPress email fails. Either the message never leaves your server, or it leaves and gets rejected or sent to spam on the way. The fix is the same in both cases, but knowing which one you have saves a lot of guessing.

Why WordPress Email Is Unreliable by Default

WordPress sends every email through its wp_mail() function. Out of the box, that hands the message to PHP’s built-in mail() function, which passes it to whatever mail software the web server has. That causes problems in three ways:

  • Some hosts disable or limit mail() to stop spammers abusing their servers, so the message never leaves at all.
  • The message isn’t authenticated. It comes from a shared web server, not from a mail server your domain has authorized, so Gmail, Outlook, and Yahoo treat it as suspicious. Since 2024, Gmail and Yahoo require proper authentication from senders, which makes this worse.
  • Forms often send “from” the visitor’s address. A message that claims to come from someone@gmail.com but leaves your server is exactly what spoofing looks like, and receiving servers reject it.

The reliable fix is to send WordPress email through a proper email service over SMTP or an API, from an address on your own domain, with DNS records that prove you’re allowed to.

Step 1: Find Out Where the Email Is Failing

Install a free mail logging plugin such as WP Mail Logging, then trigger an email: submit your contact form, or request a password reset for a test user. Check the log:

  • No entry at all: WordPress never tried to send it. Check the form’s notification settings, and make sure the action you tested actually sends email.
  • An entry with an error: the message failed on your server. Your host may block mail(), or an SMTP setting is wrong. The error text usually says which.
  • An entry with no error, but nothing arrives (not even in spam): the message left your site and was rejected or filtered later. That’s an authentication problem, which Steps 2 to 4 fix.

Step 2: Send Through an SMTP or API Email Service

Use a plugin to route wp_mail() through a proper sending service. WP Mail SMTP, FluentSMTP, and Post SMTP are all widely used. For the service itself, you have two kinds of options:

  • A transactional email service such as Brevo, Mailgun, Postmark, Amazon SES, or SendLayer. These are built for website email and give the best deliverability. Most have a free or cheap tier that covers a typical site.
  • Your own mailbox’s SMTP server, such as Google Workspace, Microsoft 365, or your host’s email. That works for low volumes but has sending limits, and Google and Microsoft increasingly require OAuth sign-in instead of a password, which the SMTP plugins support.

Wherever you can, choose the service’s API connection in the plugin instead of plain SMTP. It’s usually faster, and it isn’t affected by hosts that block outgoing SMTP ports.

In the plugin’s settings:

  • Set the From Email to an address on your own domain, such as hello@yourdomain.com.
  • Turn on the option to force that From address (in WP Mail SMTP it’s Force From Email), so every plugin uses it.
  • Choose your service as the mailer and paste in its API key or SMTP details.

Step 3: Add the DNS Records Your Email Service Gives You

Your email service will ask you to add DNS records to your domain to prove it may send on your behalf. Add exactly the records it shows in its domain setup screen, at your DNS provider (Cloudflare, your registrar, or your host). There are three kinds:

  • SPF, a TXT record listing which services may send email for your domain.
  • DKIM, a TXT or CNAME record holding a public key, which lets receiving servers check that messages really came from your service and weren’t changed.
  • DMARC, a TXT record at _dmarc.yourdomain.com that tells receivers what to do when SPF or DKIM fails.

Two mistakes cause most failures here:

  • Two SPF records. A domain may have only one SPF record. If you already have one (for example for Google Workspace), add the new service’s include: to it rather than creating a second record. With two, SPF fails for both. A combined record looks like v=spf1 include:_spf.google.com include:yourprovider.example ~all, using the exact include value your provider gives.
  • Skipping DMARC. If you don’t have a DMARC record yet, start with a monitoring-only one:
Host: _dmarc
Type: TXT
Value: v=DMARC1; p=none; rua=mailto:dmarc-reports@yourdomain.com

DNS changes can take a while to apply. Most email services show a “verified” status for each record once they can see it.

Step 4: Send a Test Email

Use your SMTP plugin’s test tool (in WP Mail SMTP, WP Mail SMTP → Tools → Email Test) and send a message to a Gmail or Outlook address. In Gmail, open the message, click the three-dot menu, and choose Show original. SPF, DKIM, and DMARC should all show PASS. If one fails, its DNS record is wrong or hasn’t updated yet.

Fix Contact Form Settings

Form plugins like Contact Form 7, WPForms, Fluent Forms, and Gravity Forms each have their own notification settings, and they’re the most common reason form emails fail when other WordPress emails work:

  • Set the form’s From address to your own domain address, the same one your SMTP plugin uses.
  • Put the visitor’s email in the Reply-To field instead, so you can still reply to them directly.
  • Check the To address for typos, and make sure the notification is actually enabled.

If Email Still Doesn’t Arrive

  • Check the email service’s own logs. Most show every message with its delivery status, and say whether the receiving server rejected it and why.
  • Ask your host about outgoing ports if you use plain SMTP and get connection timeouts. Many hosts block ports 25, 465, or 587. Switching the plugin to the service’s API avoids the problem.
  • Check for a conflict. Two SMTP plugins active at once, or a snippet that changes wp_mail, can override your settings. Test with only your SMTP plugin active. See diagnosing plugin conflicts.
  • Protect your forms from spam with a honeypot, Cloudflare Turnstile, or reCAPTCHA. Spam submissions can use up your sending quota and hurt your domain’s reputation.

Testing Email on a Local Site

On a local development site, don’t send real email at all. Tools like Local catch every message WordPress sends in a built-in inbox (Mailpit, under the site’s Tools tab), so you can check content and formatting safely. It’s also how the recovery mode email in our critical error guide was captured.

Summary

Log your emails first, to see whether they fail on your server or after leaving it. Then send through a proper email service with an SMTP plugin, from an address on your own domain, and add the exact SPF, DKIM, and DMARC records the service gives you, with only one SPF record. Check that all three pass in a test email, and fix form notifications to use your domain as From and the visitor as Reply-To.