Back to tutorials
Tutorial

cPanel Email Routing Tutorial (2026): Fix Local vs Remote Mail Delivery After DNS or Server Changes

cPanel email routing tutorial for 2026: fix Local vs Remote delivery, MX issues, split DNS, and Exim routing after migrations.

By Anurag Singh
Updated on Jul 05, 2026
Category: Tutorial
Share article
cPanel Email Routing Tutorial (2026): Fix Local vs Remote Mail Delivery After DNS or Server Changes

Email “works” until you move DNS, add an external mailbox provider, or migrate accounts. Then messages bounce, loop, or land on the wrong server. This cPanel email routing tutorial walks through the checks to run in WHM/cPanel and on the command line. You’ll fix Local vs Remote delivery without guessing.

Before you change anything: identify the failure mode in 5 minutes

Most routing issues fit one of four patterns. Identify your pattern first.

If you don’t, you’ll waste time flipping settings at random.

  • Mail lands on the wrong server (for example, a cPanel mailbox receives mail even though you use Microsoft 365/Google Workspace).
  • Mail bounces with “Unrouteable address” or “No Such User Here” right after a migration.
  • Mail loops between two servers or retries forever.
  • Outgoing works, incoming doesn’t (often MX, firewall, or rDNS/PTR confusion).

Quick evidence to collect:

  • The domain and one affected mailbox (for example, user@example.com).
  • One full bounce (including headers) or the message ID from the sender.
  • The current public DNS view for MX and A records.

If you’re working on a production box and want fewer surprises, a managed VPS hosting plan from HostMyCode keeps routing, Exim basics, and DNS safety checks under one support umbrella.

Step 1 — Verify public DNS (MX and A) from the server

Don’t rely on your laptop’s resolver or cached results. Query DNS from the cPanel server itself.

This shows what the server sees.

dnf -y install bind-utils 2>/dev/null || true
apt-get update && apt-get -y install dnsutils 2>/dev/null || true

# Replace example.com
DOMAIN=example.com

# MX records
( command -v dig && dig +short MX $DOMAIN ) || ( command -v host && host -t mx $DOMAIN )

# A/AAAA of the primary MX host
MXHOST=$(dig +short MX $DOMAIN | sort -n | head -1 | awk '{print $2}' | sed 's/\.$//')
dig +short A $MXHOST
dig +short AAAA $MXHOST

# What does the domain itself point to?
dig +short A $DOMAIN
dig +short AAAA $DOMAIN

What you want to see:

  • If cPanel should receive mail: MX should point to your server’s hostname (or to the domain itself if you use the A record pattern).
  • If an external provider should receive mail: MX must point to that provider, and your cPanel server should not be handling inbound for that domain.

Pitfall: split DNS or stale TTL. If some resolvers still use the old MX, delivery becomes intermittent.

That also makes the problem hard to reproduce.

For low-downtime DNS changes, follow HostMyCode’s DNS cutover tutorial with TTL checks and rollback.

Step 2 — Check cPanel’s Email Routing setting (Local vs Remote)

cPanel stores a per-domain routing choice. That setting can override what you assume DNS is doing.

It’s the most common reason mail “keeps going to the old place.”

In cPanel (per account):

  1. Log in to cPanel for the domain.
  2. Go to EmailEmail Routing.
  3. Choose one:
  • Local Mail Exchanger: this server accepts mail for the domain.
  • Remote Mail Exchanger: mail should go elsewhere (Microsoft 365, Google Workspace, another mail server).
  • Automatic: cPanel decides based on DNS, but it’s often wrong during migrations or with unusual MX setups.

In WHM (server-wide view):

  1. WHM → search Email Routing Configuration or MX Entry tools.
  2. Confirm the routing mode for the domain and the expected destination.

Simple rule: if the domain’s MX points away from your cPanel server, set it to Remote. If MX points to your cPanel server, set it to Local.

During cutovers, avoid “Automatic” until things settle.

If you’re migrating cPanel accounts between servers, set routing deliberately on both sides during the overlap window.

The cPanel Transfer Tool tutorial pairs well with this, because it helps you keep ownership clear while DNS catches up.

Step 3 — Confirm the domain is considered “local” by Exim

After you change the setting in the UI, confirm Exim agrees.

If Exim still treats the domain as local, it will keep attempting local delivery.

Check whether Exim treats the domain as local:

DOMAIN=example.com

# On cPanel servers, local domains are typically listed here:
grep -R "^${DOMAIN}$" /etc/localdomains /etc/remotedomains 2>/dev/null || true

# Also check secondary files if present:
ls -l /etc/localdomains /etc/remotedomains

Interpretation:

  • If the domain appears in /etc/localdomains, Exim will attempt local delivery.
  • If the domain appears in /etc/remotedomains, Exim will send outbound to the MX target.

If these files don’t match what you set in cPanel, rebuild the domain lists:

/scripts/updateuserdomains
/scripts/checkallsslcerts --allow-retry 2>/dev/null || true

Then re-check /etc/localdomains and /etc/remotedomains.

Step 4 — Diagnose MX precedence and “backup MX” surprises

MX records have priorities. Lower numbers win.

If an old cPanel host is still the lowest-priority MX, it will keep catching mail.

DOMAIN=example.com
# show priorities and targets
for r in $(dig +short MX $DOMAIN | sort -n); do echo "$r"; done

Common mistakes:

  • Two MX records with the same priority pointing to different providers. Senders may choose either one.
  • A “backup MX” pointing to a retired server. Mail queues somewhere and never clears.
  • MX points to a hostname with no A/AAAA. Some senders fail immediately.

If you’re using an external mailbox provider, keep only that provider’s MX records.

If you truly need a backup MX, use an actual relay service. Test it during a controlled failure.

Step 5 — Test routing with a real SMTP conversation (no waiting)

If DNS looks correct and the cPanel setting looks correct, test what the system will actually do.

Start with Exim’s view. Then talk to the MX host directly.

From the cPanel server, check what MX it would use:

DOMAIN=example.com
exim -bt postmaster@$DOMAIN

You want output that clearly shows the path. It should show either local delivery or a remote transport.

If it insists on local when it should be remote, the server still treats the domain as “local” somewhere.

From any Linux box (or the VPS itself), test the MX host directly:

DOMAIN=example.com
MX=$(dig +short MX $DOMAIN | sort -n | head -1 | awk '{print $2}' | sed 's/\.$//')

# Basic SMTP banner and RCPT test
( echo "EHLO test"; echo "MAIL FROM:<test@$DOMAIN>"; echo "RCPT TO:<postmaster@$DOMAIN>"; echo "QUIT" ) | nc -v $MX 25

If port 25 is blocked on the receiving side, you’ll see timeouts or immediate rejects.

If you suspect firewall issues on your VPS, follow this targeted guide: Firewall troubleshooting tutorial.

Step 6 — Fix the classic “mail loops between two servers” scenario

Loops happen when Server A thinks the domain is remote and forwards to MX, but MX points back to Server A.

Sometimes Server B sits in the middle and forwards it back.

Headers usually make this obvious. Look for repeated “Received:” lines that alternate hosts.

Checklist to break the loop:

  1. Pick the authoritative inbound server for the domain (one server only).
  2. Set DNS MX to that server (and remove competing MX records).
  3. On the non-authoritative cPanel box, set Email Routing to Remote Mail Exchanger.
  4. On the authoritative cPanel box, set it to Local Mail Exchanger.
  5. Rebuild domain lists: /scripts/updateuserdomains.

If the loop involves an external provider, check for a connector/forwarder rule.

It may be sending the mail right back to the same domain via SMTP.

Step 7 — Handle “Remote Mail Exchanger” without breaking webmail and autoresponders

Setting a domain to Remote tells Exim not to accept local delivery for that domain. That’s correct when mail lives elsewhere.

Users will notice side effects quickly:

  • cPanel mailboxes on this server won’t receive new mail for that domain.
  • Webmail (Roundcube) may still show old messages stored locally, which confuses users.
  • Autoresponders and forwarders created in cPanel won’t trigger for inbound messages, because inbound mail no longer arrives here.

If you need webmail and server-side rules, keep mail local or move those rules to the external provider.

Trying to “half host” mail across two systems usually turns into a support treadmill.

Step 8 — Audit and clean up local mail artifacts after switching to remote

After you cut over to Microsoft 365 or Google Workspace, old cPanel mailboxes often remain. They won’t receive new mail, but they still consume disk.

They also confuse users who log into webmail.

Do this carefully, and only after delivery has been stable for a while:

  • List mailboxes for the account in cPanel → Email Accounts.
  • Remove unused mailboxes (or at least set quotas low and document what you kept).
  • Check Maildir size under /home/USERNAME/mail/ (server-side).
# Example: find large local maildirs (be cautious)
du -sh /home/*/mail 2>/dev/null | sort -h | tail -20

If you want a safer operational pattern, pair cleanup with a restore plan.

HostMyCode’s VPS backup verification tutorial shows how to prove restores work before you delete anything users might ask for later.

Step 9 — Fix routing after a cPanel migration: the “new server is ready, mail still hits the old server” trap

During migrations, you often run both servers in parallel. Web traffic can switch quickly.

Email usually lags because senders cache MX results. They may also retry for hours.

Practical migration routing approach:

  1. 24–48 hours before cutover: lower MX TTL (e.g., 300 seconds) on the authoritative DNS.
  2. At cutover: change MX to the new server and keep the old server accepting mail for a short overlap window.
  3. On the old server: set the domain to Remote once you’re confident the new MX has propagated. This stops the old server from “catching” mail again.
  4. Queue watch: confirm no backlog remains on the old server before shutdown.

If you need a hosting-grade migration path (including pre-checks and rollback), HostMyCode offers assisted moves via HostMyCode migrations.

Step 10 — Quick Exim log reads that tell you routing is wrong

On most cPanel deployments, Exim is the truth source. The main log shows what happened.

It may not match what the UI implies.

Common locations:

  • /var/log/exim_mainlog
  • /var/log/exim_rejectlog
# Show the last 200 lines of activity
TAIL=200

tail -n $TAIL /var/log/exim_mainlog

# Filter for a domain (incoming + outgoing)
DOMAIN=example.com
grep -i "${DOMAIN}" /var/log/exim_mainlog | tail -n 80

# Look for routing clues: local delivery, remote_smtp, defer
egrep -i "(local_delivery|remote_smtp|defer|R=|T=)" /var/log/exim_mainlog | tail -n 80

What to look for:

  • local_delivery when you expected it to go remote.
  • remote_smtp when you expected local mailbox delivery.
  • Defers mentioning “Connection timed out” to the MX host (network/firewall) or “Host lookup did not complete” (DNS).

Step 11 — Don’t confuse email routing with authentication (SPF/DKIM/DMARC)

Routing decides where mail goes. Authentication decides whether recipients accept it and where it lands.

Once routing is correct, align auth with what you’re actually doing:

  • If you send outbound from cPanel but receive inbound elsewhere, SPF must include your cPanel server IP.
  • If you no longer send from cPanel, remove its IP from SPF and disable DKIM signing on the server for that domain.

For a complete, hosting-friendly auth setup, use: Email authentication setup tutorial. It keeps SPF/DKIM/DMARC aligned so you don’t “fix routing” and still get bounces.

Step 12 — A practical routing checklist you can reuse for every domain

  • DNS: MX points where you intend; no competing records; TTL is appropriate for the change window.
  • cPanel Email Routing: explicitly Local or Remote; avoid Automatic during transitions.
  • Exim domain lists: domain appears in the correct file (/etc/localdomains or /etc/remotedomains).
  • Connectivity: port 25 reachable to the inbound MX; no firewall rules blocking SMTP.
  • Logs: Exim shows the expected transport (local vs remote_smtp) and no defers.
  • Cleanup: remove stale local mailboxes after remote cutover (only after backups/verification).

Summary: keep one source of truth for mail, and make cPanel match it

Most routing incidents come down to one mismatch: DNS says “remote,” but cPanel still treats the domain as local (or the reverse).

Once public MX records, Email Routing mode, and Exim’s local/remote domain lists all agree, delivery gets boring again.

If you’d rather not babysit mail settings, run cPanel on a HostMyCode VPS or move to dedicated servers when you need consistent throughput and cleaner isolation across multiple accounts.

If you’re migrating domains or switching email providers and want predictable results, HostMyCode can host your cPanel stack on managed VPS hosting or move your accounts with migration help. Expect clear routing checks, DNS safety steps, and the boring kind of email delivery you actually want.

FAQ

Should I use “Automatic” or set Local/Remote manually?

Set Local/Remote manually during DNS changes and migrations. Consider Automatic only after things are stable and you understand your MX design.

My MX points to Microsoft 365, but cPanel still receives mail. Why?

The domain is probably still marked as local on the server (/etc/localdomains) or Email Routing is set to Local/Automatic. Set Email Routing to Remote and rebuild domain lists with /scripts/updateuserdomains.

Can I keep a few cPanel mailboxes while the rest are on Google Workspace?

Not cleanly. SMTP routing is per domain, not per mailbox. Mixed hosting often leads to missed mail, loops, and constant support work.

After migration, how long can email keep hitting the old server?

Hours, sometimes longer, because senders cache MX and retry previously resolved hosts. Lower TTL ahead of time and keep a short overlap window before setting the old server to Remote.

Where do I check if Exim is sending locally or remotely?

Check /var/log/exim_mainlog for local_delivery vs remote_smtp, and confirm whether the domain is listed in /etc/localdomains or /etc/remotedomains.

cPanel Email Routing Tutorial (2026): Fix Local vs Remote Mail Delivery After DNS or Server Changes | HostMyCode