Confirm what DNS is telling senders right now
mail.example.com, and only change its A record. In that case the MX TTL is not the one that matters. The A record's TTL is. The reverse also happens: the MX moves to a new hostname, but the old hostname still resolves to the old server, and anything that cached the old MX keeps connecting there.
Compare the authoritative answer with what a public resolver returns:
BASH
# What your zone's authoritative nameserver publishes (replace ns1.example.net)
dig +noall +answer MX example.com @ns1.example.net
# What a public resolver currently returns, including the remaining TTL
dig +noall +answer MX example.com @1.1.1.1
# If the MX hostname did not change, check its A record as well
dig +noall +answer A mail.example.com @1.1.1.1Find late arrivals in the old server's logs
/var/log/mail.log on Debian and Ubuntu, or /var/log/maillog on RHEL-family systems. Exim writes to /var/log/exim_mainlog on cPanel servers and /var/log/exim4/mainlog on Debian. Older entries are usually in rotated and compressed files, so use zgrep for those.
BASH
# Postfix: successful deliveries to the domain that did not go out over SMTP
grep 'to=<[^>]*@example.com>' /var/log/mail.log | grep 'status=sent' | grep -v 'relay=smtp'
# Exim: group log lines per message for the domain, then show delivery lines
exigrep '@example.com' /var/log/exim_mainlog | grep '=>'relay=local, relay=virtual, or a Dovecot/LMTP relay, depending on how mailboxes are delivered. The matching smtpd line with client= shows which host handed over the message. In Exim, <= marks a message arriving, => a delivery, == a deferral, and ** a permanent failure. The T= field on a delivery line shows the transport. Local transport names vary by configuration, but they are easy to tell apart from remote_smtp.
The timestamps matter most. Any local delivery after the cutover is a message the customer has not seen. Also check where these messages came from. Some are external senders with stale DNS. Others come from the old server itself, such as a web form or cron job still running there. In Postfix, those enter through the pickup service. In Exim, they arrive locally rather than from a remote host. They keep arriving no matter what DNS says, because they never use it.
Check the queue separately from the mailboxes
BASH
# Postfix: queue summary line, deferred mail by destination, one message in full
postqueue -p | tail -n 1
qshape deferred
postcat -q QUEUE_ID
# Exim: message count, first part of the listing, headers of one message
exim -bpc
exim -bp | head -n 50
exim -Mvh MESSAGE_IDStop local delivery and move what is already there
mydestination, virtual_mailbox_domains, or similar, depending on the setup). Then add a transport entry such as example.com smtp:[203.0.113.10] to the file your transport_maps points to, run postmap on that file, and reload Postfix. The square brackets tell Postfix to connect to that address directly instead of looking up MX records, which avoids depending on the old server's own resolver cache. Queued messages for the domain keep their old routing until you run postsuper -r ALL, which requeues them so the new transport applies.
On cPanel, the equivalent is changing the domain's Email Routing from local to a remote mail exchanger. Exim then routes the domain by its MX record, so first confirm that the old server itself resolves the new MX. Otherwise it may route mail back to itself.
For mail already delivered, copy it mailbox to mailbox over IMAP from the old server to the new one. Tools like imapsync are built for this. They are typically designed to skip messages already copied when you run them again, which suits a final delta pass. Run the copy after you have stopped local delivery, so nothing new lands behind you.
One warning for the shutdown step. Turning the old server off, or closing port 25, while it still accepts mail locally does not lose anything new. Senders get a connection failure, defer, and usually reach the new server on retry. However, any mail delivered to old mailboxes before that point stays there unless you copy it. Deleting the server or its disks before the final copy permanently loses those messages. Treat that step as irreversible and do it last.
Verify before you switch it off
- Public resolvers return only the new MX and A records, with no backup MX pointing at the old host.
- The old server's logs show no local deliveries for the domain since you changed its routing.
- Its queue has no messages for the domain, and any remaining outbound mail has been delivered or handled on purpose.
- A final IMAP sync pass copies nothing new.
- Any scripts or cron jobs that sent mail from the old server have been moved or disabled.
