Adding a contact form that actually reaches you
Contact forms fail when the From address is faked, authentication is missing, or mail routing is misconfigured. Learn to set the form headers correctly, publish SPF and DKIM records, add a DMARC policy, and test so you know where messages go if they do not arrive.
A contact form works when three things line up: the form sends to one mailbox you actually read, the message is authenticated as your domain, and the server routes mail to the right place. Set the form’s From to an address on your own domain, put the visitor in Reply-To, send via SMTP with authentication, and fix SPF, DKIM and DMARC in cPanel. Then test end to end so you can see where a message went if it does not arrive.
This picks up from a WordPress site already running on cPanel hosting that you can log in to, and a domain you control.
Before you start
- Access you need: WordPress admin for your site and cPanel for the hosting account. You also need access to the mailbox that will receive the messages, even if that mailbox is on Microsoft 365 or Google Workspace.
- Where form messages go: in WordPress and most form plugins, the messages go exactly to the “To” address you set in the form’s mail settings. There is no hidden inbox.
- Authentication matters: unauthenticated form mail often lands in spam or gets rejected by Gmail and Yahoo. Fix SPF and DKIM in cPanel’s Email Deliverability. Add a DMARC record in cPanel’s Zone Editor and start at policy p=none so you can monitor before enforcing.
- Bad idea to avoid: setting From to the visitor’s email. This breaks DMARC alignment. Keep From on your domain and put the visitor in Reply-To instead.
- Routing pitfall: if your website is on cPanel but your mailbox lives elsewhere, set Email Routing to Remote in cPanel. Leaving it on Local can make the server deliver to a non-existent local mailbox instead of sending to your external MX.
- Spam filtering risk: if Auto-Delete is enabled in cPanel’s Spam Filters, messages above the threshold are discarded and cannot be recovered. Disable Auto-Delete while testing.
- Quota: a mailbox that is over quota cannot receive mail. Check cPanel’s Email Accounts and Email Disk Usage.
- PHP mail(): some servers block unauthenticated script mail with “Prevent ‘nobody’ from sending mail”. If mail() does nothing, use SMTP with authentication from your form or WordPress.
Step 1: Choose one destination mailbox and write it down
Decide which inbox will receive your form messages. Use something your team already reads, not a new address you will forget to check. If that mailbox is external, for example Microsoft 365 or Google Workspace, you will set Email Routing to Remote in a later step.
WordPress note: in Contact Form 7, the “To” field in the Mail tab is where you set this. In custom PHP, it is the recipient you hand to your mailer library.
Undo: if you change your destination later, update the form’s “To” address and, if you move between on-server and external mail hosting, also update cPanel’s Email Routing in Step 5.
Step 2: Authenticate your domain in cPanel (SPF and DKIM), then add DMARC
Authenticated mail is far more likely to be accepted and stay out of spam. cPanel provides the tools.
- In cPanel, open Email Deliverability. Use the Repair or Install option for your domain to publish SPF and DKIM records. This creates or fixes the TXT and CNAMEs cPanel needs for valid signatures and sending authorisation.
- If your DNS is not hosted on this cPanel, copy the suggested records to your actual DNS provider instead. Publish them there, then return to Email Deliverability and re-check.
- Still in cPanel, open Zone Editor for the domain and use Add DMARC record. Start with the default and set a monitoring policy: for example a TXT record with
p=none. This lets you collect reports and see alignment without blocking mail. When SPF and DKIM align consistently, you can move top=quarantineorp=reject.
Why this matters: Gmail and Yahoo tightened rules in 2024. Bulk and many routine senders are expected to have valid SPF and DKIM, plus a DMARC policy. DMARC alignment fails if you forge the visitor’s address in From, which is why you will keep From on your own domain in Step 3.
Undo: if DMARC enforcement starts causing legitimate mail to be quarantined or rejected, change the DMARC record back to p=none in Zone Editor while you investigate. You can also remove the DMARC TXT record to disable it, then re-add later.
Step 3: Configure the form’s From, To and Reply-To the right way
Set three headers correctly. This is the single most common cause of “the form sends, but nothing arrives”.
- To: set this to the destination mailbox from Step 1.
- From: set this to an address at your site’s domain that you control, for example a real mailbox you created in cPanel. This keeps SPF, DKIM and DMARC aligned with your domain.
- Reply-To: set this to the visitor’s email so you can reply directly. In WordPress, add a “Reply-To:” line in Additional headers if your plugin provides that field. In code or PHPMailer, use
addReplyTo().
WordPress with Contact Form 7: the To field decides the destination. The From must be a valid mailbox syntax. Put the visitor’s address in Reply-To in Additional headers. Contact Form 7’s own guidance recommends using a From on your domain with SPF/DKIM set up, then Reply-To for the visitor.
Custom PHP with PHPMailer: send via SMTP with authentication. Use setFrom() to an address on your domain that you own, and addReplyTo() with the visitor’s address. If you use a Gmail account as the sender, Gmail will only allow the account itself or a verified alias in From.
Undo: if you previously used the visitor’s address in From, change it back to an address on your domain and move the visitor’s address to Reply-To. This alone often fixes spam classification.
Step 4: Send mail via SMTP with authentication, not PHP mail()
SMTP with authentication ties the message to a real mailbox. Servers that block mail from “nobody” or that do not relay unauthenticated mail will then accept and relay your form messages.
- WordPress: install an SMTP plugin and configure it to use a cPanel mailbox. In cPanel, open Email Accounts, then Set Up Mail Client to see the server name, username and ports. Use port 587 with STARTTLS or port 465 with SSL, authenticate with the mailbox’s full address and password, and set the plugin’s From to the same domain address you chose in Step 3.
- PHPMailer: follow the SMTP example. Enable SMTP, set the host, port 587 with TLS or 465 with SSL, enable SMTPAuth, and use your cPanel mailbox credentials. Keep
setFrom()on your domain, and useaddReplyTo()for the visitor.
Undo: to revert a WordPress SMTP plugin to the default behaviour, disable the plugin or switch its setting back to PHP mail if it provides a toggle. Remove the stored SMTP password if you do not want it saved. In custom code, set SMTP off to fall back to the server’s MTA.
Step 5: Set Email Routing correctly in cPanel
cPanel needs to know whether to deliver mail for your domain locally or send it to the internet. If this is wrong, the webserver may drop form mail into a non-existent local mailbox.
- In cPanel, open Email Routing.
- If your destination mailbox is on this cPanel account, choose Local Mail Exchanger.
- If your destination mailbox is hosted externally, for example Microsoft 365 or Google Workspace, choose Remote Mail Exchanger. This tells cPanel to send to your domain’s external MX records instead of trying to deliver locally.
Undo: if you later move mail back onto this cPanel, return Email Routing to Local. If you move away to external MX, change it to Remote at the same time as you update your DNS. Either mismatch can cause bounces or messages disappearing into the wrong server.
Step 6: Keep Spam Filters safe while testing
Check Spam Filters in cPanel. If Auto-Delete is on, turn it off for now so no tests are discarded silently. If you use Spam Box, check that folder in webmail or your mail client during tests.
Undo: re-enable Auto-Delete only if you need it after you confirm form mail is arriving and correctly scored.
Step 7: Check mailbox quota and disk usage
A full inbox will not receive mail. In cPanel, open Email Accounts and check the Storage Used column for your destination mailbox. If it is near or above the quota, increase the quota or clear space using Email Disk Usage.
Undo: if you raised a quota temporarily, reduce it again to your normal policy once tests are complete.
Step 8: Test end to end and trace what happens
Now prove that a submission goes from the form to the inbox, and gather evidence if it does not.
- Send live tests: submit your form a few times using realistic content. Vary the visitor address, including one at Gmail and one at a business domain.
- Check WordPress side: Contact Form 7 does not store submissions. If you want a temporary record while debugging, install Flamingo. It stores submissions so you can confirm the form ran even if mail is filtered. You can remove it later.
- Use cPanel Track Delivery: open Email, then Track Delivery. Search for the recipient or your test subject. Look at recent events. Click the info icon for each message to see if it was accepted, deferred, filtered or rejected, along with any SMTP response.
- Inspect authentication at the recipient: in Gmail, open the message and use Show original. Check SPF, DKIM and DMARC say pass. If any fail, revisit Step 2 and Step 3.
- Run a mail-tester check: go to mail‑tester.org, copy the temporary address it shows, set your form’s To to that address or send a test from your site if your plugin supports it, then analyse the result. Fix the reported issues and re‑run until your score is healthy.
Undo: if you changed your form’s To for mail‑tester, put it back to the real destination when done. If you installed Flamingo only to debug, deactivate or remove it when you no longer need stored submissions.
Step 9: Cut down bot spam without breaking delivery
- Contact Form 7 + reCAPTCHA v3: enable it via Contact → Integration, then enter your keys. This reduces bot traffic hitting your mail flow.
- Akismet with Contact Form 7: enable integration to filter out clear spam before it triggers a mail.
Undo: to disconnect reCAPTCHA, remove the keys in the Integration screen. To stop Akismet checks, disable that integration in Contact Form 7.
Step 10: If it still does not arrive, use the evidence and get help
- Check that From is an address on your domain, not the visitor. If you used the visitor, DMARC alignment will fail and large providers may junk or reject the mail.
- Reconfirm Email Routing: Local for on-server mail, Remote for external MX.
- Reopen Email Deliverability. SPF and DKIM should be present and valid. Fix any reported problems.
- Read the error in Track Delivery. A 550 or 5.7.x usually explains why the recipient refused the message.
- Check your SMTP plugin’s logs or debug output. Authentication failures, wrong ports or TLS settings will show there.
- If you built a custom PHP form and still use mail(), switch to SMTP with authentication. Some servers block unauthenticated mail from scripts.
If you are on our hosting and cannot get a test through, open a support ticket with the exact time of a failed submission, the destination address, and a screenshot of Track Delivery’s detail. We can review the server logs.
What next
- Harden your DMARC policy once SPF and DKIM are aligned. Move from
p=nonetop=quarantineorp=rejectin cPanel’s Zone Editor after monitoring. - Standardise transactional mail from your site with the same authenticated mailbox you set here. That keeps password resets and order emails out of spam too.
- If you later decide to host your site or mail on a VPS, see our Linux VPS range. You can learn more in our VPS guides.
Common questions
Can I set From to the visitor’s email so replies go straight to them?
No. That breaks DMARC alignment and is a common reason for form mail going to spam or being rejected, especially by Gmail and Yahoo. Set From to an address on your domain and put the visitor’s address in Reply-To. Your mail client will still reply to the visitor, and authentication will pass.
Do I really need DMARC?
Yes for best results. Add a DMARC record in cPanel’s Zone Editor with policy p=none first so you can monitor. When SPF and DKIM align for all your legitimate senders, move to quarantine or reject. Jumping to reject before alignment is fixed will block legitimate form mail.
Where are my Contact Form 7 submissions stored?
They are not stored by Contact Form 7 itself. If you need a record while you sort delivery, install the Flamingo plugin. It saves submissions so you can see what the form produced even if a message is filtered elsewhere.
Our mail is on Microsoft 365 or Google Workspace. What should Email Routing be?
Set Email Routing to Remote in cPanel. That tells the server not to deliver locally and to use your domain’s external MX records instead. Leaving it on Local can make the webserver deliver to a non-existent local mailbox or misroute messages.
Does WordPress send mail without an SMTP plugin?
Yes, WordPress uses the server’s mail transfer agent by default. If that is unavailable or deliverability is poor, use an SMTP plugin and authenticate with a cPanel mailbox. By default, Reply-To equals From unless you set it explicitly in your plugin, which is why adding a Reply-To with the visitor’s address is important.