The contact form says "Thank you, your message has been sent", a customer places an order, someone asks for a password reset, and no email arrives: not in the inbox, sometimes not even in spam. Nothing on the site looks broken, which is why this one can go unnoticed for months while enquiries are lost. In most cases it is one cause: WordPress hands the email to the web server, and the receiving mail provider does not trust mail from that server in your domain's name. Below is a rebuilt example (not a real client), then how to confirm the cause, the fix and the test.
The owner's inbox after a test enquiry
orders@harborlinebakery.example
What the checks found
Why it happens
Out of the box, WordPress sends every email (form notifications, WooCommerce orders, password resets, new-user mail) through the web server's own PHP mail function, from an address like wordpress@yourdomain.com. Three things then go wrong, alone or together:
The server is not allowed to send for your domain. Your domain's SPF record lists who may send its mail (say Google Workspace or Microsoft 365). The web server is not on that list and the mail carries no DKIM signature, so the check fails. Since February 2024 Gmail and Yahoo require mail to pass SPF or DKIM, and they reject or bin mail that passes neither.
The host limits or switches off PHP mail. Many hosts cap it at a few messages an hour or disable it, and some block outgoing mail ports on cheaper plans. WordPress is not told; the form still says "sent".
The form sends "from" the visitor. A form set to use the customer's address (jane@yahoo.com) as the From line asks your server to send mail in Yahoo's name. Providers that publish a strict DMARC policy, Yahoo and AOL among them, tell receivers to reject exactly that.
First, five minutes of checks
Send yourself a password reset from the login page (Lost your password?) to an address at Gmail or Outlook, not to an address on your own domain. If it does not arrive within five minutes, the problem is the whole site's mail, not one form.
Look in spam, then in Gmail open the message (if it arrived) and use the three-dot menu, Show original. The top lists SPF, DKIM and DMARC each as PASS or FAIL. Any FAIL is the cause.
Look up your domain's SPF record with any free DNS lookup tool (a TXT record starting v=spf1). Note who it names. If it names your mailbox provider only, the web server is not allowed to send.
Open the form's notification settings (Contact Form 7: the Mail tab; WPForms, Gravity Forms: Notifications) and read the From field. It should be an address on your own domain, not a merge tag for the visitor's email.
The fix
Send through a real mail service, not the web server. Install one SMTP plugin (WP Mail SMTP, FluentSMTP and Post SMTP are the common free ones) and connect it to the service that already sends your domain's mail: Google Workspace, Microsoft 365, or your host's mailbox. For a shop or a busy form, a transactional service (Brevo, Mailgun, Postmark, SendGrid, Amazon SES) is built for it and most have a free tier. If the host blocks mail ports, choose the plugin's API option for that service instead of plain SMTP.
Use one From address on your own domain, the same one the service is set up to send as, for example hello@yourdomain.com. In the SMTP plugin, tick the option that forces this From address so every plugin uses it.
Put the service in your DNS. Add its include to the one SPF record (never a second v=spf1 record; two records make SPF fail outright), and add the DKIM record the service gives you. If you have no DMARC record yet, a starting one is a TXT record at _dmarc with v=DMARC1; p=none; rua=mailto:you@yourdomain.com. More on that in the DMARC guide.
Fix the form's From line. From: your domain address. Reply-To: the visitor's email field. Replying still goes straight to the customer, and nothing is sent in Yahoo's name.
WooCommerce only: in WooCommerce, Settings, Emails, check that each email you rely on (New order, Processing order, Customer invoice) is enabled and that "New order" names the right recipient. A disabled email looks exactly like a delivery failure.
Test: the SMTP plugin's own test email arrives in a Gmail inbox, not spam; Show original reads SPF PASS, DKIM PASS, DMARC PASS; a real enquiry through the live form arrives with the customer as Reply-To; a password reset arrives; a test order sends both the shop's and the customer's email. Keep an email log plugin on for a week to catch anything that still fails.
What you see, what it means, what it needs
What you see
Usual cause
Usual fix
Form says "sent", nothing arrives anywhere
Host disabled or capped PHP mail, or the receiver rejected it
SMTP plugin through a real mail service
Mail arrives, but in spam
SPF or DKIM fails for your domain
Add the service to SPF, publish its DKIM key
Some enquiries arrive, Yahoo or AOL senders never do
Form sends From the visitor's address
From = your domain, Reply-To = visitor
Arrives at Gmail, not at the address on your own domain
Domain mail is hosted elsewhere, but the web server thinks it handles your domain's mail and delivers it to itself
Send through the mailbox provider; ask the host to set mail routing to "remote"
Worked for months, stopped suddenly
Host changed limits, the SMTP password or app password changed, or a second SPF record was added
Check the SMTP plugin's log; one SPF record only
WooCommerce order email missing, others fine
That email is disabled or has the wrong recipient
WooCommerce, Settings, Emails
"Could not instantiate mail function" or "SMTP connect() failed"
Mail function off, or the mail port is blocked
SMTP plugin, using the service's API option if ports are blocked
What not to do
Do not add a second SPF record for the new service. Merge it into the one you have; two records count as an error and every message fails SPF.
Do not set DMARC to p=reject before the test above passes. It tells receivers to throw away exactly the mail you are trying to fix.
Do not paste your main email password into the SMTP plugin. Use the provider's connect button, an app password, or an API key made for the site, so a site problem never exposes your mailbox.
Do not trust the form's "sent" message as proof. It only means WordPress handed the mail over, not that anyone received it.