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.

Similar Posts