splitforms.com
← Back to the journal

WordPress Contact Form Not Sending Email? 9 Fixes That Work

WordPress contact form not sending email? Nine fixes for wp_mail and PHP mail failures, from SMTP setup and SPF/DKIM/DMARC to a plugin-free form backend.

Start free — 500 submissionsSee pricing →No card, no time limit. Pro is $5 per month.
Short answer
A WordPress form that "sends nothing" almost always fails on the email leg, not the form. Every form plugin hands the message to wp_mail(), which by default uses your host's unauthenticated PHP mail() — and that last hop is where WordPress emails die. Confirm the notification is on and routed correctly, then work through the nine fixes in order: from an SMTP plugin and SPF/DKIM/DMARC records to a plugin-free form endpoint that stores every entry.
Try it on your own form

Point any HTML form at one endpoint. 500 free submissions — no card, no time limit — and unlimited forms.

Create free account

The root cause: wp_mail() and unauthenticated PHP mail

When a visitor submits any WordPress contact form — Contact Form 7, WPForms, Gravity Forms, Elementor, Ninja Forms — the plugin validates the fields, saves the entry, and then asks WordPress to send the notification. WordPress routes that through wp_mail(), which by default calls the server's PHP mail() function. That last hop is where the email dies:

  • Many shared hosts disable or throttle outbound PHP mail to fight spam abuse, so the message never leaves the server.
  • The message is sent unauthenticated — no SPF/DKIM alignment — from an IP shared with other sites, so Gmail and Outlook spam-folder it by default.
  • Failures are silent: the plugin logs the notification as sent because wp_mail() accepted it, but no bounce or error reaches wp-admin.

This is the same plumbing behind every "form works but no email arrives" report, and it hits every plugin identically. The entry itself is almost always saved, so the lead is not gone; only the notification email is. The nine fixes below are ordered from the quickest setting check to the permanent fix that removes wp_mail from the path entirely.

Nine fixes, in order

1. The host blocks or limits PHP mail() / wp_mail

Before touching any plugin, prove where the mail stops. Install a plugin-free check such as WP Mail Logging, or run the email test in WordPress → Tools → Site Health, and send a test message. If the log shows the message was handed to PHP mail() but nothing arrives, your host is blocking or throttling outbound mail — the most common cause on shared hosting. Some hosts cap the number of messages per hour, so a form that works in the morning can silently fail after a burst of submissions. Confirm the failure is at the mail layer, not the form, before moving on.

2. No SMTP: set up an SMTP plugin with your mail provider

The standard fix is to stop using the host's PHP mail and send through an authenticated SMTP account. Install WP Mail SMTP, FluentSMTP or Post SMTP and connect a real mail provider — Google Workspace, Brevo, Mailgun or Amazon SES. Now wp_mail(), and therefore every form plugin's notification, sends through an account with proper SPF/DKIM instead of the server's unauthenticated PHP mail, and notifications start landing in the inbox. Use the plugin's built-in test-email tool afterwards to confirm delivery. Cost: a plugin to maintain plus SMTP credentials to keep secure.

3. The From address doesn't match the domain, so mail fails SPF/DMARC

In the form plugin's notification settings, set the From Email to an address on a domain you control — for example forms@yourdomain.com — instead of a default like wordpress@yourdomain.com or a no-reply address on a different domain. If the From domain is not the one your DNS authorizes for sending, the message fails SPF and DMARC alignment and gets filtered. Put the visitor's address in Reply-To so replies still reach the person who filled in the form. This is necessary, but on shared hosting it is rarely sufficient by itself — pair it with fix 2.

4. SPF, DKIM and DMARC records are missing

Even authenticated mail can be spam-folded if your DNS does not say your sender is allowed to send for your domain. Add an SPF record covering your mail provider, enable DKIM signing at the provider and publish the keys in DNS, and add a DMARC policy (start with p=none and monitor before tightening). Check each record with the free SPF checker, DKIM checker and DMARC checker. A missing or misconfigured record here is a frequent reason mail that "was sent" never reaches the inbox.

5. Emails land in spam

If the message is delivered but sits in the junk folder, the cause is deliverability, not the form. Unauthenticated, shared-IP mail from a From address that fails DMARC is exactly what mailbox providers filter. Send through an authenticated provider (fix 2), set the From Email to your own domain (fix 3), and publish SPF, DKIM and DMARC (fix 4). Ask the recipient to add the sender to their contacts and mark the message as not spam so the provider trusts it going forward. The full breakdown of why notification mail gets filtered is in why contact form emails go to spam.

6. A wrong recipient address in the plugin's notification settings

Open the form's notification settings in the plugin and confirm the Send To address is the inbox you actually read. It is often an old address, a departed employee's mailbox, or a shared inbox nobody monitors. Watch for a stray comma or space that creates a malformed recipient, and for a default tag like {admin_email} that points at the wrong address. Check any conditional logic on the notification — a rule that does not match the submission means the notification simply never fires. Fix the address and resubmit a test form.

7. A caching or security plugin blocks the AJAX submit

If the form sometimes submits and sometimes does not — or the entry is created but the notification never fires — a caching plugin serving stale HTML or a security plugin blocking the AJAX request can be the cause. A cached page can serve an expired nonce, so the submit is rejected as a security check. Temporarily disable page caching and security/anti-spam plugins, resubmit the form, and confirm the notification fires. If it does, re-enable them one at a time and allowlist the form's AJAX endpoint so the nonce is always fresh.

8. A plugin or theme conflict

If nothing above is the cause, test for a conflict. Switch to a default theme (such as Twenty Twenty-Four) and deactivate all plugins except the form plugin, then resubmit. If the email arrives, reactivate plugins one at a time until the failure returns — that plugin is the culprit, and you can then look for a setting or a compatibility update. A theme that overrides the form's markup or enqueues a script that intercepts the submit can break it the same way. This isolates a third-party cause you would otherwise chase forever.

9. Skip wp_mail entirely: point the form at a hosted form backend

If you would rather not depend on wp_mail at all, take WordPress out of the submission path and point a plain HTML form at a hosted endpoint. With splitforms, the form POSTs to https://splitforms.com/api/submit with a hidden access key:

<form action="https://splitforms.com/api/submit" method="POST">
  <input type="hidden" name="access_key" value="YOUR_ACCESS_KEY" />
  <input name="name" type="text" placeholder="Name" required />
  <input name="email" type="email" placeholder="Email" required />
  <textarea name="message" placeholder="Message" required></textarea>
  <button type="submit">Send</button>
</form>

Every accepted entry is stored in a searchable dashboard before the owner notification email is attempted, so a mail failure can never lose a lead. Spam is filtered by automatic spam scoring plus a honeypot, and notifications are sent from deliverability-managed infrastructure with SPF, DKIM and DMARC handled for you. Because the form posts straight to the backend, it does not depend on your host's PHP mail, a caching plugin, or a plugin conflict. See adding a contact form to WordPress without a plugin and the free contact form page for the full walkthrough.

Plugin-specific guides

The fixes above apply to every WordPress form plugin. If you want the settings walked through for the exact plugin you use, start with the guide for it:

Other form problems and fixes

Still stuck? Test your endpoint with our free Form Action Tester or contact splitforms support.

FAQ

Why is my WordPress contact form not sending email?

Almost always because the email leg fails, not the form. Every WordPress form plugin hands the message to wp_mail(), which by default calls your host's unauthenticated PHP mail(). Shared hosts often block or throttle that mail, and receiving servers spam-folder it because it has no SPF/DKIM alignment. The submission is usually still saved in the plugin, so the lead is not gone — only the notification email is. Work through the nine fixes in order, starting with confirming the notification is on and routed to the right address.

Does WordPress need an SMTP plugin to send form email?

Not strictly, but on most shared hosts it is the reliable fix. WordPress sends through wp_mail(), so installing an SMTP plugin such as WP Mail SMTP, FluentSMTP or Post SMTP and connecting a real mail provider (Google Workspace, Brevo, Mailgun, Amazon SES) gives the message proper SPF/DKIM authentication instead of the server's unauthenticated PHP mail. You then own the SMTP credentials and the provider's deliverability settings, and notifications start landing in the inbox.

Why do my WordPress form emails go to spam?

Because they leave your web server through PHP mail() with no SPF/DKIM alignment, often from an IP shared with many other sites, and often with a From address that fails DMARC. Mailbox providers treat that unauthenticated, shared-IP mail as suspicious by default. Send through an authenticated provider with an SMTP plugin, set the From Email to an address on your own domain, and publish SPF, DKIM and DMARC records for that domain. The full breakdown is in the guide to why contact form emails go to spam.

Can I send WordPress form email without wp_mail at all?

Yes — bypass WordPress mail entirely and point a plain HTML form at an external form endpoint. With splitforms, the form POSTs to https://splitforms.com/api/submit with a hidden access key, every accepted entry is stored in a searchable dashboard before the owner notification email is attempted, spam is filtered by automatic spam scoring plus a honeypot, and delivery runs on managed infrastructure with SPF, DKIM and DMARC handled for you. The saved dashboard record remains available if email fails, so a bad mail day never loses a lead.

Stop depending on wp_mail — point your form at https://splitforms.com/api/submit and every lead is stored, filtered, and emailed. Get a free access key.

Related: why contact form emails go to spam, contact form works but no email, and the free contact form.

Related articles

More practical guidance from guides.

Browse the journal →
Guides

Elementor Form Not Sending Email? 5 Fixes That Work (2026)

Why Elementor form notifications never arrive: the wp_mail root cause, how to confirm it in…

8 min readRead →
Guides

WPForms Not Sending Email? 6 Fixes That Work (2026)

WPForms notifications not arriving? Find the wp_mail cause in 2 minutes, then fix it with si…

7 min readRead →
Guides

Ninja Forms Not Sending Email? 8 Fixes for WordPress

Ninja Forms notifications not arriving? Learn why wp_mail fails, how to check email actions…

7 min readRead →

Explore this topic

Start with the overview, then move into focused guides.

OverviewContact Forms for Every FrameworkStart here →GuideContact Form for Next.jsRead →GuideContact Form for ReactRead →GuideContact Form for VueRead →ReferenceContact form guideOpen →

Building forms with ChatGPT, Claude, Cursor, or v0? Connect the native MCP server and give your agent a production form backend.

Explore the MCP server →

Give your form a production backend.

One endpoint adds delivery, spam filtering, storage, and integrations. Start with 500 free submissions — no card, no time limit.

Create free accountRead the docs →
Secure checkoutSSL encryptionPrivacyProtected
VISAAMERICANEXPRESSstripe