Website Email Problems
WordPress Emails Not Sending
Last reviewed
Direct answer
WordPress does not run its own mail server—it hands messages to PHP mail() or to an SMTP/API plugin you configure. When contact forms, password resets, or WooCommerce notices never arrive, install authenticated SMTP (or a transactional API), use a From address on your domain, and fix SPF/DKIM so receiving servers accept the mail.
Silent email failure is one of the most common WordPress operations problems: the form says “sent,” but the inbox stays empty. The root cause is almost always transport (host blocking PHP mail), authentication (bad SMTP credentials), or DNS (missing SPF/DKIM), not a random WordPress bug. This guide walks through how to prove whether mail left the server, how to wire a reliable sender, and how to stop guessing with DNS records.
What the error means
WordPress exposes wp_mail() as a thin wrapper around PHPMailer. By default that library calls PHP’s mail() function, which depends on a local MTA (sendmail-compatible binary) that many shared hosts throttle, rewrite, or disable for abuse control. Contact form plugins, WooCommerce, and core password-reset mail all share that same pipeline unless you override it with an SMTP plugin or provider API (SendGrid, Mailgun, Amazon SES, Postmark, Google Workspace, Microsoft 365, and similar). Even when transport succeeds, inbox providers reject or spam-folder messages that lack domain-aligned From addresses and valid SPF/DKIM—and ideally a DMARC policy that tells receivers what to do on failure.
Common symptoms
- Contact form shows a success message but nothing lands in inbox or spam
- Password reset and new-user emails never arrive for admins or customers
- WooCommerce order, shipping, or failed-payment emails missing on one or both sides
- SMTP or mail-log plugins report authentication failed, connection timed out, or connection refused
- Delivery works to Gmail but fails for Microsoft 365 (or the reverse)
- Site Health, WP Cron, or email log tools record wp_mail failures with timestamps
- Messages arrive hours late only when someone visits the site (cron starvation)
Most likely causes
- 01 Host blocks or rate-limits PHP mail() and/or outbound port 25
- 02 No SMTP plugin or transactional email API configured after a migration
- 03 Wrong SMTP hostname, port, encryption mode (TLS vs SSL), or revoked app password
- 04 From address spoofs a free Gmail/Yahoo address or a domain the server is not allowed to send as
- 05 Missing, duplicate, or incomplete SPF TXT records; DKIM not published for the sending provider
- 06 Form notification To/Reply-To misconfigured or conditional logic sending to an empty field
- 07 Security, firewall, or “disable REST/cron” plugins blocking outbound connections or wp-cron
What changed before the problem started
- Site moved to a new host that no longer allows unauthenticated PHP mail
- DNS edited at the registrar and an old SPF record was overwritten or duplicated
- SMTP password rotated, mailbox deleted, or OAuth/app-password revoked
- Contact form plugin, WooCommerce email settings, or From address changed
- Host disabled mail() after a spam complaint or policy update
- Transactional provider account suspended or API key expired
Troubleshooting steps
- 01
Prove whether WordPress can hand off mail at all
Install a reputable SMTP or mail-logging plugin and send a test message to an address you control. If the log shows a transport failure, fix SMTP/API first. If the log shows success but nothing arrives, check spam folders and move on to SPF/DKIM—do not keep reinstalling form plugins.
- 02
Configure authenticated SMTP or a provider API
Prefer TLS on port 587 (or the provider’s documented HTTPS API) using the exact SMTP host from your email vendor’s docs—not a guessed hostname. Store credentials in the plugin settings or server environment variables, never in a public theme file or committed repo.
- 03
Align the From name and From email with your domain
Use an address such as noreply@yourdomain.com or forms@yourdomain.com that exists or is authorized as send-as on your mailbox provider. Sending “from” a personal Gmail address through your web server’s IP is a frequent cause of silent rejection.
- 04
Repair SPF and publish DKIM at your DNS host
Maintain a single SPF TXT record that includes every real sender (host mail, Google Workspace, transactional provider via include:…). Add the DKIM CNAME or TXT records your provider supplies. Wait for DNS propagation, then resend a test. Two competing SPF records cancel each other out—merge them.
- 05
Audit form and WooCommerce notification settings
Open each form’s notification: confirm To addresses, Reply-To (usually the submitter), and that conditional routing is not empty. In WooCommerce → Settings → Emails, confirm the emails you expect are enabled. Test one personal inbox and one second-provider inbox to catch provider-specific filtering.
- 06
Rule out security plugins blocking outbound mail
Temporarily relax firewall rules that block external API/SMTP connections or that disable wp-cron. If mail starts working, allowlist your mail provider’s endpoints instead of leaving the firewall off.
When to stop troubleshooting
Escalate when SMTP authenticates and DNS looks correct but major providers still reject or disappear mail, the host blocks all outbound SMTP without offering an API path, or the domain appears on blocklists you cannot clear alone. Do not keep cycling random SMTP hostnames—hand off with mail-log errors, current SPF text, and a list of which message types fail.
Information to collect before requesting help
- 01 Which message types fail (forms, password reset, WooCommerce, admin alerts, all of them)
- 02 SMTP or mail-log error text and approximate timestamp
- 03 From address in use and intended recipient addresses
- 04 Hosting company and mailbox/DNS provider
- 05 Full current SPF TXT value and whether DKIM is enabled for the sender
- 06 Recent host migrations, DNS edits, or password rotations
- 07 Screenshot of form/WooCommerce notification settings with secrets redacted
How a professional repairs the problem
We determine whether failure is at PHP transport, SMTP authentication, or recipient filtering. Then we wire authenticated SMTP or an API sender, set domain-aligned From addresses, correct SPF/DKIM/DMARC, and retest form and WooCommerce notifications end-to-end. Mail logging is left enabled so the next failure is visible instead of silent.
Frequently asked questions
Why does the contact form say success if email never arrives? +
Is PHP mail() enough for a business WordPress site? +
Should contact forms ask for passwords or card numbers? +
Do I need both SPF and DKIM? +
Can a security plugin stop WordPress email? +
Will changing hosts break WordPress email? +
Repair dispatch
Still Need Help Fixing Your Website?
If you are not comfortable editing website files, changing server settings, repairing a database, or troubleshooting a live website, professional help may prevent additional damage or downtime. We will review the problem before accepting the repair.
- You will receive a clear explanation of the likely cause.
- We will tell you if the issue falls outside our repair scope.
- No additional work will be performed without approval.
- A backup should be created whenever access and website condition allow it.
Do not share passwords through an unencrypted contact form.