What spam protection looks like from both sides
Contact Form 7 deliberately shows spammers the same sentence as everyone else. Its FAQ calls not revealing the detection “a kind of worldly wisdom”: a real spammer should not learn they were caught, and a wrongly flagged visitor should not be called a spammer. Useful for defence, confusing for debugging, so know the signs:
| What you see | What it means | Where to act |
|---|---|---|
| Bot submissions arriving in your inbox | No spam module is on; all three ship disabled | Turn on Turnstile below |
| Error message with an orange border | A spam module blocked the submission | Fine if it was a bot; check the log if not |
| Error message with a red border | Not spam: the mail itself failed to send | the error guide |
| Real visitors report the orange error | A module is flagging legitimate submissions | Spam logging, below |
Turnstile: the defence Contact Form 7 recommends
Since version 6.1, Contact Form 7 has a built-in Cloudflare Turnstile module, and its documentation is direct about the choice: “We recommend Turnstile unless you have reasons to use reCAPTCHA.” Unlike reCAPTCHA, Turnstile is free, and most visitors never solve a puzzle; it judges them from browser signals.
- Create a Turnstile widget in your Cloudflare account (a free account is enough) and choose the Managed mode, which the plugin's docs recommend. Copy the site key and secret key.
- In WordPress, go to Contact → Integration, find the Turnstile section and select Setup integration.
- Paste both keys and save. In the docs' words: “Now, all of your contact forms automatically have the Turnstile widget.”
By default the widget sits at the top of the form. To move it, put a [turnstile] form-tag where you want it in the form template; options such as size:compact and theme:dark go inside the tag. On an older Contact Form 7, update the plugin first: before 6.1 you needed a separate Turnstile plugin, and two Turnstile widgets on one form is its own source of breakage.
The disallowed list: your own block rules
The third defence reuses WordPress's own comment moderation list. Under Settings → Discussion → Disallowed Comment Keys, one entry per line, you can put words, email addresses and IP addresses; Contact Form 7 checks submissions against the same list. A casino keyword, a repeat offender's IP or a throwaway mail domain each take one line, and the matching submission gets the orange border. To learn a spammer's IP in the first place, the docs suggest adding the special mail-tag [_remote_ip] to the email template.
Treat it as a scalpel, not a shield. Each entry also applies to blog comments, a short word matches inside longer words, and a list built in anger (“free”, “offer”) starts blocking customers. Use it for the specific junk that keeps coming back after Turnstile and Akismet are on.
When real messages start getting the orange border
Every defence above can misfire, and because the visitor sees the generic sentence, your first report of it will be a customer saying the form “doesn't work”. The way to see what actually happened is Contact Form 7's spam logging feature, which the FAQ points to for exactly this: it records which module blocked each submission, so you can tell a Turnstile failure from an Akismet verdict from a disallowed-list match.
Then act on the module, not on the feeling: an overbroad disallowed-list entry gets deleted, Akismet learns when you mark false positives as not spam, and a Turnstile widget in a stricter mode than Managed can be relaxed. One more thing worth knowing: Contact Form 7 does not store submissions, so a blocked message is gone unless you also run Flamingo, the companion plugin that keeps submissions, spam included. Installing Flamingo before you tighten the screws means a false positive is a message you recover, not one you lose.
Or filter spam after the form, not in it
All three defences run inside WordPress, which is also the thing bots probe all day. The other approach is to let the form post to a backend that filters on the server. With Formgong, the form keeps its fields, the action points at our endpoint, and spam is handled there: a honeypot field, a server-side filter, and optional Cloudflare Turnstile you switch on in the form settings without keys in your theme. Flagged submissions land in a Spam folder in the dashboard instead of disappearing, so a false positive is one click to restore. The free plan takes 1,000 submissions a month with email and Telegram delivery.
How the honeypot and the other checks work together is in how to prevent form spam without a captcha; the WordPress setup is on the WordPress integration page.
Did the flood stop?
Which of the three did it for your form, or is spam still getting through all of them? Write to support@formgong.com and tell us what you tried. The cases readers send are how these guides get better.
Frequently asked questions
How do I stop spam in Contact Form 7?
Turn on one of the plugin's three built-in defences: Cloudflare Turnstile under Contact → Integration (recommended by the plugin's own docs, needs a free Cloudflare site key and secret key), Akismet via akismet: options on your form-tags, or the disallowed list shared with WordPress comments.
Does Contact Form 7 have spam protection by default?
No. Turnstile, Akismet and the disallowed list all ship switched off, which is why a fresh form starts collecting bot submissions. Turning on Turnstile is the quickest fix.
Why does Contact Form 7 show an orange border error?
The orange border means a spam module blocked the submission; the FAQ names Akismet, reCAPTCHA and the disallowed list as the possible sources. The plugin shows spam and mail failures the same sentence on purpose, so use the spam logging feature to see which module fired.
Does Contact Form 7 save messages blocked as spam?
Not by itself: Contact Form 7 stores no submissions at all. Install Flamingo, the companion plugin by the same developer, and submissions including spam are kept, so false positives can be recovered.
Sources and documentation
Official references for this guide: Contact Form 7: Cloudflare Turnstile integration, Contact Form 7: Spam filtering with Akismet, Contact Form 7: Comment blocklist, Contact Form 7: FAQ (orange border, spam logging). WordPress, where data is stored.
Related guides
- Lovable form submissions to email and Telegram
- HTML contact form without a backend: a working example
- How to send website form submissions to Telegram
- Contact form not sending email? Check where it stops
- Managing website leads in Telegram without a CRM
- Form backend for Lovable, Bolt, v0, Cursor
- Telegram bot for a contact form: build or skip?
- GDPR form backend: 7 checks before you choose
- Lovable form not sending email? 6 fixes
- Netlify Forms not working? React and Bolt fixes
- Stop contact form spam without a CAPTCHA
- GitHub Pages contact form: a working setup
- Mailto Form in HTML: Why It Fails and What to Use
- HTML form to Google Sheets: 2 free methods
- Webflow form submission limit: what to do at 50
- Turnstile vs reCAPTCHA vs hCaptcha for forms
- Contact Form 7 and Elementor forms to Telegram
- Squarespace contact form not sending email?
- Shopify contact form: where do messages go?
- Google Form to Telegram: free Apps Script way
- Wix contact form not sending email? Fixes
- EU / GDPR Formspree alternatives compared
- HTML form action attribute explained
- How do HTML forms work? The HTTP request
- Types of Injection Attacks on Web Forms (2026)
- Indirect Prompt Injection in MCP
- MCP Rug Pull Attack: Detect Tool Changes
- Form without a backend: 7 ways that work
- Thank-you page after form submission (HTML)
- Indirect Prompt Injection Examples (2023–2026)
- Indirect Prompt Injection via Email
- What Is Tool Poisoning in MCP?
- WordPress contact form without a plugin
- Send email from frontend JavaScript
- How to Prevent Indirect Prompt Injection
- Honeypot Form Field: How to Add One That Works
- Contact Form with File Upload (HTML, No PHP)
- Angular contact form without a backend
- Send form submissions to Slack or Discord without Zapier
- Verify a form webhook signature (HMAC-SHA256)
- Contact forms that send nothing: 793 AI-built sites tested
- v0 contact form that actually sends: 3 ways
- How we tested AI-built contact forms, and 12 bugs we hit
- Cloudflare vs Netlify free plan: hosting that never pauses
- EmailJS 412 “Gmail_API: Invalid grant”: reconnect Gmail
- Resend “You can only send testing emails”: verify a domain
- Supabase Edge Function blocked by CORS policy: 3 causes
- Formspree “Form not found” and other errors: fixes
- Web3Forms errors: “Invalid access key” and 403 explained
- How to add customer reviews to your website for free
- Getform not working? “This form has been deleted” and more
- Next.js contact form not working? 6 errors, reproduced
- Webflow form not sending email? What to check, tested
- FormSubmit not working? “This form needs Activation” fix
- Contact form “TypeError: Failed to fetch”: causes and fixes
- WooCommerce product enquiry form
- Contact Form 7 vs WPForms
- Gravity Forms alternative free
- WordPress contact form block
- 535-5.7.8 Username and Password not accepted (Gmail)
- 535 5.7.3 Authentication unsuccessful: Office 365 SMTP
- Nodemailer “Missing credentials for "PLAIN"”: the fix
- Nodemailer “Greeting never received”: port 465 fix
- Nodemailer SSL “wrong version number”: the port fix
- Nodemailer “self-signed certificate in certificate chain”
- Nodemailer ECONNREFUSED 127.0.0.1:587: missing SMTP host
- SendGrid “authorization grant is invalid”: 401 fix
- Mailgun 401 Forbidden: why the API rejects your key
- “Edge Function returned a non-2xx status code”: the fix
- Next.js “Body exceeded 1 MB limit”: Server Action fix
- Unexpected token '<', "<!DOCTYPE "... is not valid JSON
- “TypeError: Body is unusable”: body has already been read
- Turnstile “timeout-or-duplicate” and other siteverify errors
- Turnstile vs hCaptcha vs reCAPTCHA: speed and size tested
- Judge.me reviews not showing on Shopify: how to fix it
- Judge.me review carousel not showing: how to fix it
- Yotpo reviews not showing on Shopify? Check the app embed
- Loox reviews not showing on product page: how to fix
- Shopify reviews not showing: what to check first
- How to show reviews on Shopify
- GDPR for website forms: what each type of form needs
- WooCommerce reviews not showing: how to fix it
- Stamped.io reviews not showing on Shopify: how to fix it
- Etsy reviews not showing: why and what to do
- Trustpilot widget not loading: how to fix TrustBox
- Yotpo problems in 2026: what merchants report
- Contact Form 7 “error trying to send your message” fix
- Elementor form “Your submission failed because of an error”
- Framer form not sending email or not working: what to check
- Carrd contact form not working: plans, spam and errors
- Google review link not working: what customers see and why
- tawk.to widget not showing on your website: causes and fixes
- How to add questions and answers to your product page
- “Failed to send a request to the Edge Function”: fixes
- Next.js “Failed to find Server Action”: what it means
- Brevo “unauthorized: Key not found” 401: the fix
- Amazon SES “Email address is not verified”: the fix
- Shopify contact form not working: how to fix it
- Judge.me alternative for WooCommerce after the 2025 shutdown
- Free WooCommerce review plugins compared on the free version
- WooCommerce review reminder emails without a paid plugin
- Add Voice Recording to a Website Form
- WPForms not sending email: how to fix it
- Contact form emails going to spam: how to fix it
- HTML form not submitting: how to fix it
- Contact form not working: how to find the fault
- Webflow form spam: how to stop it
- Website form to Notion: how to set it up
- Website form to WhatsApp: what works and what does not