Contact Form 7 Not Sending Email
This is a Step by Step for Solving This Particular Issue with NameCheap
Change [account] and [IP]to your servers settings. This was for a Namecheap registered domain. You will need to adjust if using another registar.
All cmds where run as root, except for those noted as being run in the Terminal under the relevant cPanel account. This assumes your cpanel account has ‘shell’ or ‘Jailed Shell’ enabled
What the issue was
The domain [account] was registered/hosted in DNS at Namecheap, using these authoritative nameservers:
dns1.registrar-servers.com.
dns2.registrar-servers.com.
cPanel had generated the local DKIM key, but the public DKIM TXT record was missing or malformed in the real DNS zone. SPF was also missing. Gmail was rejecting messages with:
550-5.7.26 Your email has been blocked because the sender is unauthenticated.
Gmail requires all senders to authenticate with either SPF or DKIM.
DKIM = did not pass
SPF [server.kool-gadgets.com] with ip: [[server_IP]] = did not pass
The important concept is: DKIM signing/key generation is local to the server, but SPF/DKIM/DMARC TXT records must be published wherever DNS is actually hosted. In this case, that was Namecheap, not cPanel Zone Editor.
After the correct records were added, Gmail accepted the Contact Form 7 message with:
250 2.0.0 OK
The email then landed in Spam, meaning delivery/authentication was fixed, but Gmail reputation/filtering still placed it in Spam. Your later log showed the old Gmail rejections before the DNS fix and the successful accepted message afterward.
Step-by-step fix outline
Step 1 — Set variables
Run as root or from server terminal:
DOMAIN="[account]"
CPUSER="[user]"
SERVER_IP="[server_IP]"
DKIM_SELECTOR="default"
Step 2 — Check where DNS is hosted
dig +short NS "$DOMAIN"
Expected result for this case:
dns1.registrar-servers.com.
dns2.registrar-servers.com.
That means DNS is at Namecheap, so do not rely on cPanel Zone Editor or Email Deliverability “Repair” to publish DNS.
Use:
Namecheap ? Domain List ? [account] ? Manage ? Advanced DNS
Step 3 — Confirm local DKIM key exists
uapi --output=jsonpretty --user="$CPUSER" EmailAuth ensure_dkim_keys_exist domain="$DOMAIN“
Good result looked like:
“msg” : “key is acceptable”,
“status” : 1
That means the server-side/local DKIM key exists.
Step 4 — Check DKIM DNS status
uapi --output=jsonpretty --user="$CPUSER" EmailAuth validate_current_dkims domain="$DOMAIN“
The original bad result was:
“state” : “MISSING”,
“records” : []
That meant the DKIM DNS record was not published.
Then after adding it incorrectly, the bad result was:
“state” : “MALFORMED”
“reason” : “The record is not a valid list of DKIM tags and values.”
That happened because the whole instruction text was pasted into Namecheap’s value field, like:
Type: TXT Record Host: default._domainkey Value: v=DKIM1…
The value must only start with:
v=DKIM1; k=rsa; p=
Step 5 — Add/fix DKIM in Namecheap
In Namecheap Advanced DNS, add or edit:
Type: TXT Record
Host: default._domainkey
Value: v=DKIM1; k=rsa; p=PASTE_THE_FULL_KEY_FROM_CPANEL
TTL: Automatic
For your actual [account] DKIM value, it was:
v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxfVsS3lJYWBtHLENsy2Yq31V4DFXQXjx2wndd/9IkwW0xsV6qCB1eb/DwYftixvNbA4IISKKT1q36rLKV0ph9mXN/IWv3amHOvjQNsvvr2F03X5TAXRph4oeDQqireFwMzT/Wqv/yVh1DrdDbd7I3mjrg8PQxTvFlXoloBMjSaIZVssrUuj3X+g5Mg7PwTP6M3o+M0kN+H2FJYOs82yK0xlN9tDr1aSDfyV9YtSzbmwL6mydt+oCRgUVVxBy4P45z3PjPHLU3oNcSw4wRV10gpqfdl3gDKDEEo5/ukGY3n4NS2oXIhayVBqqDon52kIZOLwqMbyjnN1bUT8TM4X3HQIDAQAB;
Important:
Host: default._domainkey
Do not use:
default._domainkey.[account]
Namecheap appends the domain automatically.
Step 6 — Check DKIM publicly
dig +short TXT "default._domainkey.${DOMAIN}" | tr -d '"'
Good output starts with:
v=DKIM1; k=rsa; p=
Bad output contains things like:
Type: TXT Record Host:
Step 7 — Validate DKIM again in cPanel
uapi --output=jsonpretty --user="$CPUSER" EmailAuth validate_current_dkims domain="$DOMAIN"
You want it to no longer show:
MISSING
or:
MALFORMED
Step 8 — Check SPF
echo "Current SPF:"
dig +short TXT "$DOMAIN" | tr -d '"' | grep -i 'v=spf1' || echo "No SPF found"echo
echo "Checking whether SPF includes $SERVER_IP:"dig +short TXT "$DOMAIN" | tr -d '"' | grep -i 'v=spf1' | grep -q "ip4:$SERVER_IP" \
&& echo "YES - SPF includes ip4:$SERVER_IP" \
|| echo "NO - SPF does not directly include ip4:$SERVER_IP"
Original result was:
No SPF found
NO – SPF does not directly include ip4:[server_IP]
Step 9 — Add SPF in Namecheap
In Namecheap Advanced DNS:
Type: TXT Record
Host: @
Value: v=spf1 +a +mx +ip4:[server_IP] ~all
TTL: Automatic
Important: only have one SPF record for the root domain. If one already exists, edit it instead of adding a duplicate.
Step 10 — Validate SPF
uapi –output=jsonpretty –user=”$CPUSER” EmailAuth validate_current_spfs domain=”$DOMAIN”
And re-check publicly:
dig +short TXT “$DOMAIN” | tr -d ‘”‘ | grep -i ‘v=spf1’
Step 11 — Check/add DMARC
Check:
dig +short TXT "_dmarc.${DOMAIN}" | tr -d '"'
If missing, add this in Namecheap:
Type: TXT Record
Host: _dmarc
Value: v=DMARC1; p=none; adkim=r; aspf=r; rua=mailto:postmaster@[account]
TTL: Automatic
Then re-check:
dig +short TXT "_dmarc.${DOMAIN}" | tr -d '"'
Step 12 — Check PTR / reverse DNS
PTR is not fixed in Namecheap unless Namecheap controls the server IP block. It belongs to the IP/server provider.
echo "PTR for $SERVER_IP:"
dig +short -x "$SERVER_IP"
echo
echo "Server hostname:"
hostname -f
echo
echo "Forward lookup for server hostname:"
dig +short "$(hostname -f)"
Ideally:
[server_IP] ? server.domain.com
server.domain.com ? [server_IP]
Validate with cPanel:
uapi --output=jsonpretty --user="$CPUSER" EmailAuth validate_current_ptrs domain="$DOMAIN"
Contact Form 7 checks
Step 13 — Confirm WordPress site and plugin
From the [user] cPanel terminal:
cd /home/[user]/public_html
/usr/local/bin/wp option get siteurl
/usr/local/bin/wp plugin list | grep -i "contact-form-7"
Your good result was:
http://[account]
contact-form-7 active none 6.1.6 off
Step 14 — List Contact Form 7 forms
When logged in as the cPanel user [user], do not use sudo.
cd /home/[user]/public_html
/usr/local/bin/wp post list \
--post_type=wpcf7_contact_form \
--post_status=any \
--fields=ID,post_title,post_status,post_type
Your form was:
ID: [ID]
Title: Contact form 1
Status: publish
Step 15 — Check Contact Form 7 mail settings
cd /home/[user]/public_html
/usr/local/bin/wp post meta get [ID] _mail
Cleaner output:
cd /home/[user]/public_html
/usr/local/bin/wp eval '
$id = [ID];
$mail = get_post_meta($id, "_mail", true);
echo "Recipient: " . ($mail["recipient"] ?? "") . PHP_EOL;
echo "Sender/From: " . ($mail["sender"] ?? "") . PHP_EOL;
echo "Subject: " . ($mail["subject"] ?? "") . PHP_EOL;
echo "Additional headers:" . PHP_EOL . ($mail["additional_headers"] ?? "") . PHP_EOL;
‘
Your settings were correct:
Recipient: [email address]
Sender/From: [_site_title] <wordpress@[account]>
Subject: [_site_title] “[your-subject]”
Additional headers:
Reply-To: [your-email]
This is correct because the From address is on the authenticated domain:
wordpress@[account]
and the visitor’s email is only used as:
Reply-To: [your-email]
Do not put the visitor’s Gmail/Yahoo/Hotmail address in the From field.
Testing delivery
Step 16 — Watch Exim log while sending a form
As root:
tail -f /var/log/exim_mainlog | grep --line-buffered -iE "[account]|gmail|spf|dkim|dmarc|<=|=>|\*\*|rejected|fail|error"
Stop with:
CTRL + C
Step 17 — Check latest Gmail sends
grep -iE "[account]|[email address]|gmail-smtp-in|250 2.0.0|550-5.7.26|\*\*" /var/log/exim_mainlog | tail -n 80
Failure looks like:
**
550-5.7.26 Your email has been blocked because the sender is unauthenticated
Success looks like:
=> [email address] … H=gmail-smtp-in.l.google.com … C=”250 2.0.0 OK … – gsmtp”
Completed
Your successful message was:
1wfaUi-00000001jUO-1Pwt => [email address] … C=”250 2.0.0 OK … – gsmtp”
1wfaUi-00000001jUO-1Pwt Completed
Final status
Original issue:
Gmail rejected [account] contact form email because SPF/DKIM were missing or invalid.
Root cause:
DNS was hosted at Namecheap, not cPanel. cPanel had the local DKIM key, but Namecheap DNS did not have the correct public DKIM/SPF records.
Fix:
Added/fixed DKIM TXT at default._domainkey.[account] in Namecheap.
Added SPF TXT for [account] authorizing [server_IP].
Added/checked DMARC.
Confirmed Contact Form 7 uses wordpress@[account] as From and Reply-To: [your-email].
Result:
Gmail no longer rejected the message.
Gmail accepted it with 250 2.0.0 OK.
Message landed in Spam, so remaining issue is Gmail spam placement/reputation, not server delivery failure.
For future domains on this server, the same pattern is:
1. Check authoritative nameservers.
2. If DNS is not hosted by cPanel, do not rely on cPanel Zone Editor.
3. Generate/check DKIM locally with cPanel.
4. Copy DKIM/SPF/DMARC TXT records into the real DNS provider.
5. Validate with uapi EmailAuth.
6. Send test.
7. Check /var/log/exim_mainlog for either Gmail 250 OK or 550 rejection.