Infrastructure8 min read

cPanel email: why the built-in mail keeps going to Spam

cPanel ships with Exim wired up, webmail working, and a "Send test" button that says everything's fine — yet Gmail buries your mail in Spam anyway. The fix is six config touches on Exim, DNS and cPanel's own knobs.

Thousands of small VPS owners run cPanel because it makes domain, DNS and email setup feel trivial. Create a mailbox, point MX at the server, hit "Send" in Webmail, done. Except Gmail quietly drops it in Spam and Outlook doesn't deliver it at all. The default cPanel mail stack is functional, but "functional" and "inbox-placing" are not the same thing in 2027.

This guide walks through the six things that go wrong out of the box on a fresh cPanel/WHM install, and exactly what to change in /etc/exim.conf.local, WHM > Email Deliverability, and DNS to get your mail actually delivered.

What cPanel sets up by default

When you provision a cPanel account and add a domain, the platform auto-generates:

  • An Exim mail server listening on ports 25, 465, 587.
  • Dovecot for IMAP/POP3 on 143/993 and 110/995.
  • An SPF record for the domain — usually v=spf1 +a +mx +ip4:<server-ip> ~all.
  • DKIM keys at default._domainkey with a 1024-bit RSA key.
  • No DMARC record. (This is the big one.)
  • No PTR record on the server IP that matches the sending hostname.

That last pair — missing DMARC and missing/mismatched PTR — is why Gmail flags your mail. Postmaster Tools treats unauthenticated senders as guilty until proven otherwise.

Fix 1: Exim config — sign with the right selector

cPanel's Exim template is solid but it rewrites the From header in ways that can break DKIM alignment if you run multiple domains on one account. Open WHM > Service Configuration > Exim Configuration Manager and switch to the Advanced Editor tab. Add these snippets to the Advanced Editor (they merge into/etc/exim.conf.local):

# /etc/exim.conf.local  (managed by WHM)
# Force submission-time DKIM signing with the domain selector
# that matches the From: header, not the server's hostname.

begin acl
acl_smtp_data:
  warn
    condition = ${if eq{$authenticated_id}{}{false}{true}}
    set acl_m_domain = ${domain:$h_from:}
    set acl_m_selector = default

# DKIM sign transport (cPanel already wires this but enforce selector)
begin transports
remote_smtp:
  driver = smtp
  dkim_domain = ${acl_m_domain}
  dkim_selector = ${acl_m_selector}
  dkim_private_key = /etc/exim/domainkeys/${acl_m_domain}
  dkim_canon = relaxed
  hosts_require_tls = *

After saving, hit "Save" (WHM validates the syntax) and restart Exim with/scripts/restartsrv_exim. Check signing is working by sending a mail to a Gmail address and inspecting the Authentication-Results header fordkim=pass with d=yourdomain.com — notd=server1234.yourhost.com.

Fix 2: DNS — publish proper SPF, DKIM, DMARC

cPanel's auto-generated SPF is too permissive and its DKIM key is weak. Replace them in WHM > Email Deliverability, or directly at your DNS host:

; SPF - lock to your actual sending server(s)
yourdomain.com.       IN  TXT  "v=spf1 ip4:203.0.113.10 -all"

; DKIM - regenerate at 2048 bits (WHM -> Email Deliverability -> Repair)
default._domainkey.yourdomain.com. IN TXT
  "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..."

; DMARC - start at p=none with reporting, tighten later
_dmarc.yourdomain.com. IN TXT
  "v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com; adkim=s; aspf=s; pct=100"

The hard-fail -all is aggressive but it's what Gmail and Microsoft want to see on a single-server setup. If you have any external senders (MailChimp, a CRM, a form backend), add them to the include list before hardening.

Regenerate DKIM at 2048 bits

cPanel still generates 1024-bit keys by default on some WHM versions. Gmail demotes DKIM pass with 1024-bit keys since 2024. In WHM > Email Deliverability, click Repair for each domain — that forces regeneration at 2048.

Fix 3: PTR / reverse DNS

The PTR record on your VPS IP must match the hostname Exim announces in HELO/EHLO. This is set at your hosting provider's control panel (OVH, Hetzner, DigitalOcean, etc.), not inside cPanel. Set PTR to your mail hostname:

# On the VPS, check what hostname Exim announces
$ hostname -f
server1234.yourhost.com

# Ideally change it to match your actual mail domain
$ hostnamectl set-hostname mail.yourdomain.com
$ systemctl restart exim

# Then at your IP provider, set PTR for 203.0.113.10 to:
#   mail.yourdomain.com

# Verify
$ dig +short -x 203.0.113.10
mail.yourdomain.com.

Also add forward A: mail.yourdomain.com => 203.0.113.10. Gmail checks FCrDNS (forward-confirmed reverse DNS) before accepting mail; mismatch is an automatic Spam vote.

Fix 4: WHM knobs that matter

Tweak Settings

  • Prevent "nobody" from sending mail: ON. Stops PHP scripts bypassing the authenticated SMTP path.
  • Restrict outgoing SMTP to root, exim, mailman: ON. Closes off local users from hitting remote port 25.
  • Track the origin of mail sent through the server: ON. Invaluable when a cPanel user's WordPress install gets hacked and starts spamming.

Email Deliverability

The built-in tool checks SPF/DKIM/PTR for every domain. Use it as a checklist, not as the source of truth — it does not test placement at Gmail/Outlook. For that, run a seed test separately.

Fix 5: Rate limits & mail send limits

A runaway WordPress site on a cPanel account can send thousands of mails/hour viamail(), torching your IP reputation. Set per-account hourly caps:

  1. WHM > Server Configuration > Tweak Settings > Mail.
  2. Set Max hourly emails per domain to 200 (or lower).
  3. Enable Number of failed/deferred messages tracking.
  4. Per-account: cPanel > Email > Track Delivery — eyeball daily for spikes.
PHP mail() is still a footgun

Even with authenticated Exim, PHP mail() skips the auth path on shared hosting and sends via a local pipe. Use an SMTP plugin (WP Mail SMTP, FluentSMTP) on every WordPress site and force mail through submission port 587 with auth. Otherwise DKIM alignment falls over the moment someone forges the From header.

Fix 6: Verify placement, don't trust "sent"

cPanel's Track Delivery shows "Delivered: Yes" the moment Exim sees a250 OK from the remote MTA. That's not the same as reaching the Inbox. Run a placement test against 20+ seed addresses across Gmail, Outlook, Yahoo, Mail.ru, Yandex after every DNS or config change:

  • Free seed mailboxes at Inbox Check — no signup.
  • Send one real email from each domain to the seed addresses.
  • Read Inbox vs Spam vs Promotions per provider, plus the rawAuthentication-Results.
  • Fix whatever fails (usually PTR or DMARC alignment), re-test.

The cPanel deliverability checklist

  1. WHM > Email Deliverability: green for every domain.
  2. DKIM at 2048 bits, selector matches From header domain.
  3. SPF hard-fails (-all), includes every real sender.
  4. DMARC at p=none with rua reporting — upgrade toquarantine after two weeks of clean reports.
  5. PTR matches forward A, FCrDNS verified.
  6. Per-domain hourly send cap configured.
  7. SMTP plugin on every PHP site, no mail() bypass.
  8. Placement test green across major providers.

Frequently asked questions

Can I just let cPanel handle all of this automatically?

The Email Deliverability tool covers SPF and DKIM, but DMARC, PTR and hourly caps are still manual. Run through the checklist above once per domain; it's a 15-minute job per domain.

Should I use a transactional provider instead of cPanel Exim for outbound?

For high-stakes mail (password resets, receipts) yes — Postmark, SES, Mailgun have better reputations than any single VPS. Keep cPanel's Exim for low-risk mail (internal alerts, cron reports) where a blip doesn't hurt.

Why is my IP clean on blacklists but Gmail still flags Spam?

Blacklists are only one signal. Gmail weighs FCrDNS, DMARC alignment, content reputation, and engagement history. A clean blacklist with broken DMARC = Spam. Fix authentication first, blacklists second.

How do I test without sending to real customers?

Use dedicated seed mailboxes. Inbox Check gives you 20+ free seed addresses across the major providers; send to them, read the verdict, iterate safely.
Related reading

Check your deliverability across 20+ providers

Gmail, Outlook, Yahoo, Mail.ru, Yandex, GMX, ProtonMail and more. Real inbox screenshots, SPF/DKIM/DMARC, spam engine verdicts. Free, no signup.

Run Free Test →

Unlimited tests · 20+ seed mailboxes · Live results · No account required