Every hour a broken contact form stays broken, you're losing leads you'll never know about. This guide gets you to the cause in minutes, whether your form won't submit or the email just isn't arriving.
Quick Diagnosis
| Symptom | Most likely cause | First thing to check |
|---|---|---|
| Green success message, no email arrives | Sender domain mismatch | Mail tab "From" address |
| Spinning wheel that never stops | JavaScript or REST API conflict | Browser console (F12) |
| Red error after submission | Mail configuration or PHP mail failure | Mail tab + SMTP setup |
| Form works intermittently | PHP mail unreliability | Set up SMTP |
| Stopped working after hosting/PHP change | PHP 8.x incompatibility | Site Health > Server |
The 5-Minute Fix That Resolves Most Cases
If your form submits but no email arrives, run this sequence first. It fixes the majority of deliverability problems before you need to touch anything else.
- Set the "From" address to your domain. In Contact > Contact Forms > Mail tab, change "From" to something like
forms@yourdomain.com. It must match your site's domain. - Install WP Mail SMTP or Fluent SMTP. Either one. Don't install both.
- Connect a mailer service. Brevo's free tier (300 emails/day) covers most small business sites. SendLayer is the easiest paid option.
- Enable "Force From Email" in the SMTP plugin settings. This locks in the authenticated From address regardless of what CF7 is set to.
- Send a test email through the plugin, then submit your contact form for real. Both should arrive.
If your form arrives in your inbox after step 5, you're done. If not, the rest of this guide walks through the less common causes.
Two Things People Mean by "Contact Form 7 Not Working"
Submission failure. The form never completes its submission cycle. You see a spinning wheel, a colored error, or a silent page reload. The cause is almost always on the WordPress side: JavaScript conflicts, a disabled REST API endpoint, a configuration error, or a plugin clash.
Deliverability failure. The form submits, you get a green success message, but no email arrives. The cause is in how the message was sent: wrong sender address, PHP mail limitations, missing authentication, or no SMTP configured.
Find your symptom below and start there.
Bucket 1: The Form Won't Submit
Before you start: Confirm a recent backup exists. If you're about to deactivate plugins or change settings, you want a restore point.
Why Is Contact Form 7 Stuck Spinning?
The loading indicator appears after you click Submit and never stops. No success message, no error. The form just hangs.
In the majority of cases, this is a JavaScript conflict. A plugin or theme is loading a script that interferes with CF7's AJAX submission. Security plugins that restrict the REST API are the next most common cause. Optimization plugins that combine or defer JavaScript can also break CF7's scripts.
Fix sequence:
- Open your browser console (F12, then click Console). Submit the form. Look for red JavaScript errors. The file name often points directly to the conflicting plugin.
- If the console doesn't give you a clear answer, run the systematic plugin deactivation process below.
- After resolving conflicts, also check the REST API and Cloudflare sections. Both produce this exact symptom and are commonly missed.
Color-Coded Error Messages: What Each One Means
CF7 uses color-coded response borders. Each color points to a different category.
- Green: Submission succeeded. If you got a green message but no email, skip to Bucket 2. The form worked. The delivery didn't.
- Yellow: Validation error. A field is missing or invalid. Check required fields and format-specific fields like email.
- Orange: Flagged as spam. Often triggered by anti-spam filters, reCAPTCHA scoring, or repetitive test submissions. Submit with realistic data.
- Red: Mail-sending failure. The submission processed but the email didn't go out. The problem is in your Mail tab configuration or your server's mail capability.
Configuration Errors in the Backend
The fastest diagnostic: use CF7's built-in Configuration Validator. Go to Contact > Contact Forms, select your form, and click "Validate Configuration." It checks all three tabs and flags errors in plain language. Run this before manually combing through settings.
Form Tab: The most common error is using a reserved WordPress parameter name. WordPress reserves names like name, author, category_name, page, s, feed, and dozens more for internal queries. If a CF7 field uses one of them, you get a conflict.
The fix is to prefix or suffix the field name. Use your-name instead of name. Use your-email instead of email. The full list of reserved names is in the CF7 documentation.
Mail Tab: Five specific errors can appear:
- Empty Subject or Message Body. Even an empty subject can trigger spam filters. Fill both fields.
- Invalid mailbox syntax in To, From, or Additional Headers. Verify formatting; CF7 expects standard mail headers like Reply-To, Cc, and Bcc in the Additional Headers field. Incorrect formatting often causes errors.
- Attachment file does not exist. Verify the file path.
- File outside the wp-content directory. Move it inside wp-content for security.
- Attachment exceeds size limit. Reduce file size or adjust your server's upload limit.
Messages Tab: Does not accept HTML tags or entities. Remove them and use plain text.
REST API Conflicts (CF7 4.8+)
Since version 4.8, CF7 submits forms through the WordPress REST API at /wp-json/contact-form-7/v1/feedback. Anything that blocks that endpoint will silently break the form or produce the spinning wheel.
Common sources of blocking: Wordfence, iThemes Security, and All-In-One Security with "Disable REST API" enabled; firewall rules blocking unauthenticated REST requests; hardening plugins that restrict the /wp-json/ namespace.
How to check: Open your browser console, submit the form, and look for a failed request containing contact-form-7. A 403 or 401 response confirms a REST API restriction.
The fix: Whitelist the /wp-json/contact-form-7/ endpoint in your security plugin, or disable the REST API restriction entirely. The CF7 endpoint is intended for public form submissions and is commonly left accessible even on hardened sites.
Cloudflare and CDN Interference
If you use Cloudflare or another CDN, three settings break CF7 frequently enough to deserve their own mention:
- Rocket Loader. Defers JavaScript in a way that frequently interferes with CF7's AJAX submission. Turn it off, or create a Page Rule to disable Rocket Loader on pages containing your form.
- Bot Fight Mode. Can challenge legitimate form submissions, especially from logged-out users. If submissions started failing after you enabled it, disable it and test.
- WAF rules. Aggressive firewall rules can block POST requests to the REST API endpoint. Check your Cloudflare Security Events log around the time of a failed submission.
This is a frequent silent failure. If you're on Cloudflare and CF7 stopped working, check Rocket Loader first.
reCAPTCHA Conflicts
CF7's reCAPTCHA v3 integration fails silently more often than most people realize. Common causes:
- Domain mismatch. The domain registered in your reCAPTCHA admin doesn't match your site exactly (www vs. non-www, http vs. https, staging vs. production).
- Script loading conflicts. Optimization plugins that defer or async the reCAPTCHA script can break the token generation.
- Score threshold too aggressive. v3 returns a risk score from 0.0 to 1.0. Some anti-spam integrations or custom implementations apply thresholds aggressively, blocking legitimate submissions. CF7's native v3 integration doesn't expose threshold tuning in its UI; you'll usually find this in the reCAPTCHA admin console or in code-level overrides.
How to check: Open the browser console and submit. A 403 response containing spam in the CF7 response, or a missing g-recaptcha-response token, points to reCAPTCHA. If you suspect reCAPTCHA, disable it temporarily by removing the site keys from Contact > Integration. If the form works without it, the integration is the problem.
Plugin and Theme Conflicts
When the console doesn't point at one file, run the systematic deactivation process. The usual offenders:
- Caching plugins (WP Rocket, W3 Total Cache): can serve stale page versions missing updated scripts.
- Optimization plugins (Autoptimize, Asset CleanUp): combining or deferring JS breaks CF7's AJAX handler.
- Security plugins (Wordfence, iThemes Security): beyond REST API issues, can block nonce verification.
- Page builders (Divi, Elementor): some builder scripts conflict with CF7 event listeners.
For more on how to identify risky WordPress plugins before they cause problems, see our maintenance and troubleshooting guide.
The deactivation process:
- Write down every active plugin. You'll be reactivating them one by one.
- In Plugins, select all and bulk-deactivate. Leave CF7 active.
- Test the form. If it works, a conflict is confirmed.
- Reactivate plugins one at a time, testing the form after each. When it breaks, you've found the conflict.
- Check for a compatibility setting or newer version. If neither resolves it, you'll need to choose which plugin to keep.
If the form still fails with all other plugins disabled, the issue is more likely server-level: firewall rules, mod_security restrictions, REST API blocking at the host level, or hosting configuration conflicts. At that point, contact your host's support or bring in a developer.
Bucket 2: The Form Submits but No Email Arrives
The green success message means the submission worked. The email didn't. This is a deliverability problem, and the fixes are entirely different from Bucket 1.
The Most Common Cause: Sender Domain Mismatch
This single issue causes most CF7 deliverability failures. When the "From" address in your Mail settings doesn't match your site's domain, receiving mail servers treat the message as potentially spoofed and route it to spam or reject it outright.
If your site is yourcompany.com but your CF7 "From" address is noreply@gmail.com or the visitor's email address, your hosting server is sending mail claiming to be from a domain it has no authority over. Mail servers are built to catch exactly this.
The fix:
Set "From" to an address on your own domain: forms@yourcompany.com or noreply@yourcompany.com. It doesn't need to be a real inbox, but the domain must match your site.
To route replies back to the form submitter, add this to Additional Headers:
Reply-To: [your-email]
This way the From address passes server checks, and replies you send from your inbox go to the visitor automatically.
Also check your spam, Promotions, and Updates folders while you're verifying the From address. Emails that arrive in the wrong folder are a separate problem (authentication, covered below) from emails that never arrive at all.
Why PHP Mail Isn't Reliable
By default, CF7 sends through wp_mail(), which uses PHP's mail() function. It works on some hosts. It fails silently on many others.
Two reasons it fails:
- Shared hosting IPs have bad sending reputation. Thousands of sites send from the same IPs. Many end up on blocklists. Your form email gets dropped or marked as spam through no fault of yours.
- Many hosts disable
mail()entirely to prevent spam originating from their servers. CF7 fails at the sending step with no useful error.
The reliable fix for both is SMTP.
Set Up SMTP (The Real Fix)
SMTP replaces PHP mail with an authenticated connection to a dedicated mail-sending service. Your site stops trying to deliver mail directly through a shared hosting IP and starts using infrastructure built for deliverability.
This is the single most impactful change you can make if your CF7 emails are going missing.
Plugin: install one, not both.
- WP Mail SMTP has broader free mailer support and a polished setup wizard. Good default.
- Fluent SMTP is fully free with no premium tier and is lightweight. Good if you want a simpler tool without upsells.
Mailer service: pick based on your situation.
| Your situation | Best choice | Why |
|---|---|---|
| Small business, low volume | Brevo | 300 free emails/day, easy setup |
| Want the simplest paid setup | SendLayer | Straightforward, good deliverability |
| Already on Google Workspace | Google Workspace SMTP | Uses credentials you already have |
| Already on Microsoft 365 | Microsoft 365 SMTP | Same logic |
| High volume, technical comfort | Amazon SES | Cheapest at scale, more setup |
For most business contact forms, Brevo's free tier or SendLayer are the practical starting points.
Setup process (any plugin and mailer):
- Install and activate your SMTP plugin.
- Select your mailer service and follow its connection wizard. It will give you an API key or SMTP credentials.
- Enable "Force From Email." This overrides whatever From address is set in CF7 and forces all outgoing mail to use the authenticated address. This is what prevents the domain mismatch issue from recurring.
- Set "Force From Name" to your business name for consistency.
- Use the plugin's built-in test email feature. Send to an address you can check immediately.
How to Verify SMTP Is Actually Working
The test email is a start, but it doesn't catch every problem. Two more steps close the loop:
- Enable email logging. WP Mail SMTP and Fluent SMTP both have a logging feature. Turn it on. You get a record of every email attempt, success or failure, including the headers and the server response. If a CF7 submission fails to send, the log tells you exactly why.
- Submit a real test through your contact form. A direct test email through the plugin uses different code paths than CF7. Always submit at least one real form to confirm the full chain works.
If the log shows messages going out but they're still not arriving, the problem has moved upstream to email authentication.
SPF, DKIM, and DMARC
If SMTP is set up correctly but emails still land in spam, the issue is almost always missing or misconfigured authentication records. These are DNS records on your domain that tell receiving mail servers your emails are legitimate.
- SPF lists the mail servers authorized to send from your domain. Your mailer service provides the record to add.
- DKIM adds a cryptographic signature to each message that receiving servers verify against a public key in your DNS. Your mailer service provides this record too.
- DMARC tells receiving servers what to do when SPF or DKIM fail. Start with
p=none(monitoring mode) so you get visibility into failures without risking legitimate mail.
How to check current status:
- MXToolbox Email Header Analyzer: paste a raw email header to see pass/fail results.
- Your mailer service dashboard usually includes an authentication check after setup.
Your mailer service will provide the exact DNS records during setup. Add them, wait up to 48 hours for DNS propagation, then recheck.
PHP Version Conflicts
Sites that upgraded to PHP 8.x without updating WordPress, CF7, or related plugins sometimes experienced form and mail compatibility issues throughout 2024 and 2025. The root cause is usually outdated plugins or deprecated functions in the surrounding stack, not PHP 8 itself.
Check your version: WordPress admin > Tools > Site Health > Info > Server.
Verify three things:
- CF7 is updated to its current version.
- WordPress core is current.
- If you're on PHP 8.0 or 8.1 and seeing issues, ask your host whether PHP 8.2 or 8.3 is available and stable on your account.
PHP version changes should be tested on staging before going live. If you don't have a staging environment, this is a good point to bring in a developer.
Don't Lose Leads While You Debug: Install Flamingo
While you're troubleshooting, real inquiries might be coming through and disappearing before you can see them.
Flamingo is a free plugin by the same developer as CF7. It stores submitted form entries in your WordPress database, independent of whether the email was delivered. A five-minute install that protects you from losing leads during the fix window.
Install it from Plugins > Add New (search "Flamingo"), activate, and go to Flamingo > Inbound Messages to see every submission. If a real inquiry came through during your downtime, it's there waiting.
When to Stop and Call a Developer
The steps above resolve CF7 problems for most sites. But there are situations where troubleshooting on your own costs more time and risk than handing it off:
- You've worked through both buckets and the form still fails.
- Multiple symptoms are appearing at once (spinning wheel, deliverability, and configuration errors together usually point to a deeper environment issue).
- The form is part of a checkout, booking, or payment flow.
- Changes you've made have made the situation worse.
At that point, a developer audit pays for itself faster than another hour of trial and error.
Our free website assessment covers plugin versions, known vulnerabilities, configuration health, and form deliverability. If you'd rather have SMTP setup and ongoing monitoring handled as part of a maintenance plan, that's included in our Small Business and Professional tiers.
For a broader look at what a WordPress maintenance plan covers, including services, costs, and packages, see our 2026 guide.
Frequently Asked Questions
Why does Contact Form 7 show success but send no email?
The green message means the form submitted correctly and CF7 attempted to send. The email not arriving is a separate deliverability issue. The most common causes are a sender domain mismatch, PHP mail unreliability on your host, or missing authentication records. Setting up SMTP resolves it in most cases.
Does Contact Form 7 require SMTP?
Not technically. CF7 uses wp_mail() and PHP mail() by default. But on most modern hosting environments, PHP mail is unreliable enough that SMTP should be considered standard, not optional. Install WP Mail SMTP or Fluent SMTP and connect a mailer service.
Why do Contact Form 7 emails go to spam?
Three causes account for almost all of them: the From address doesn't match your domain, PHP mail is sending from a shared IP with poor reputation, or your domain is missing SPF and DKIM authentication records. Setting up SMTP with proper DNS records fixes all three.
Why is Contact Form 7 stuck spinning?
A JavaScript conflict, a blocked REST API endpoint, or Cloudflare Rocket Loader. Since CF7 4.8, submissions use the REST API. If a security plugin disables it, the form hangs. Start with the browser console: a 403 or 401 response on a contact-form-7 request confirms a REST API issue.
How do I fix Contact Form 7 after a PHP 8 upgrade?
Update CF7 to its current version, update WordPress core, then verify your PHP version in Tools > Site Health > Info > Server. If you're on PHP 8.0 or 8.1 and seeing issues, ask your host about moving to 8.2 or 8.3. Test on staging first.
How do I test if Contact Form 7 is actually sending emails?
Install an SMTP plugin and turn on email logging. The log shows every send attempt with success or failure and the server's response. Combine that with Flamingo (which logs every submission to the database) and you have full visibility into both the form and the email path.
Is Contact Form 7 still being maintained?
Yes. CF7 is actively maintained by Takayuki Miyoshi, has millions of active installations, and receives regular updates. Vulnerabilities are tracked at patchstack.com and wordfence.com.
If this guide resolved the issue, your form should now be submitting and delivering reliably. If you're still seeing problems, the cause is likely environment-specific. We're happy to take a look.
Author:

Jason Long is the founder and CEO of JHMG and SupportMy.Website. He has 25 years of experience in business building, having led web-based projects across industries from agriculture to healthcare. At JHMG, he works as a SaaS Consultant helping businesses start, build, grow, scale, and exit their SaaS businesses.
Outside of work, he enjoys travel, fitness, community-focused projects, and of course spending quality time with family.
Jason Long’s Linkedin
Website: JasonMLong.me
X/Twitter: @jasonmlong