Short answer: WordPress is sending mail through PHP’s mail() function,
which is unauthenticated, so your host blocks it or the recipient’s spam
filter discards it. Install an SMTP plugin, connect it to a real mailbox,
and it starts working.
That fixes the overwhelming majority of these. Here is how to confirm it, and what to do when it is something else.
Why this happens
By default WordPress sends email using PHP’s built-in mail(). It arrives
from your web server with nothing proving it is allowed to send as your
domain.
Receiving mail servers are strict about that now, and rightly so — it is how spoofing works. So one of three things happens:
- Your host blocks it outright. Many shared hosts disable
mail()to stop spam from compromised sites. - It sends and is silently discarded. The receiving server sees unauthenticated mail claiming to be your domain and drops it. No bounce.
- It lands in spam, which is the one people eventually discover.
Your form plugin did its job in all three cases. It handed the message to
WordPress, which handed it to mail(). The failure is after that — which
is why switching form plugins never helps.
Confirm it in two minutes
Install WP Mail SMTP, then open WP Mail SMTP → Tools → Email Test and send one to an address you can check.
- Test fails → sending is broken, as expected. Carry on below.
- Test arrives but form submissions do not → sending works and the problem is in the form. Skip to the last section.
That one test splits the problem in half, which saves a lot of guessing.
The fix
In the SMTP plugin, pick a mailer and connect it to a mailbox that is allowed to send as your domain.
If you already have Google Workspace or Microsoft 365, use that. Nothing new to sign up for.
If you do not, use a dedicated sending service — Brevo, Mailgun, SendGrid and others all have free tiers big enough for a contact form. These exist to do exactly this and have better deliverability than a generic mailbox.
Your host’s own SMTP server also works and is often simplest on cPanel:
create a mailbox such as noreply@yourdomain.com and use those credentials.
Two settings catch people out:
The From address must be on your own domain. Not the visitor’s address,
and not a Gmail one. Mail claiming to be from someone@gmail.com but sent
by your server fails authentication immediately.
Put the visitor’s address in Reply-To instead. You still hit reply and it goes to them — you just do not pretend the mail came from them. Every decent form plugin has a field for this.
Then set up SPF and DKIM
With SMTP working, mail sends. Whether it reaches the inbox is a separate question, and that is what SPF and DKIM answer.
- SPF is a DNS record listing who may send as your domain
- DKIM signs each message so the recipient can verify it was not altered
Your sending service gives you both records to add to DNS. On cPanel they are under Email Deliverability, which will also tell you what is missing.
Skip this and your mail works but lands in spam, which feels like the original problem and is maddening to diagnose twice.
If the test email arrived but forms still do not
Then sending is fine and the form is the problem. Check in this order:
- The notification’s To address. Often still an old developer’s email or a default that was never changed.
- Spam, and any server-side filter. Including rules on the mailbox itself.
- Conditional logic on the notification that is quietly never met.
- A caching or optimisation plugin breaking the submission — test with caching off.
- Whether the form submits at all. Open the browser console and watch for a failed request. A JavaScript error means nothing was ever sent.
Do not rely on email alone
Email will fail again eventually — a DNS change, an expired API key, a provider outage.
Store submissions in the database as well. Most form plugins can, and it costs nothing. Then a delivery failure means a delayed enquiry rather than a lost one. I have seen businesses discover months of missing enquiries this way, and the ones that stored entries could still answer them.
Form quietly swallowing enquiries? Send me the URL — this is one of the most common things I get asked to fix, and it is usually sorted the same day.