Andrew Mercer
on this page

Email routing is driven almost entirely by DNS. Before a message can go anywhere, the sending MTA has to answer one question: which host accepts mail for this domain?

MX records

An MX (Mail Exchanger) record maps a domain to the hostname(s) that accept its mail, each with a preference (lower = more preferred):

domain.tld.    3600  IN  MX  10  mx1.domain.tld.
domain.tld.    3600  IN  MX  20  mx2.domain.tld.

A sending MTA tries mx1 first. If that host is unreachable or answers with a temporary failure, it falls back to mx2. Records with equal preference are used in random order for load spreading.

Rules worth knowing:

  • An MX target must be a hostname with A/AAAA records, never an IP address and never a CNAME.
  • No MX at all: RFC 5321 falls back to the domain's own A/AAAA record (the "implicit MX"). Small setups often rely on this by accident. Publish an explicit MX.
  • A domain that should never receive mail can say so with a null MX (RFC 7505), so senders bounce immediately instead of queueing for days: nomail.domain.tld. IN MX 0 .
  • A backup MX that can't validate recipients becomes a spam magnet (spammers deliberately target the lowest-priority MX). Today it's usually better to have one well-run MX and let senders queue for a few hours during an outage.
dig +short MX domain.tld
dig +short A mx1.domain.tld

PTR records and forward-confirmed reverse DNS

MX records tell a sender where to send. PTR records (reverse DNS) are what a receiver checks about the sender: they map the connecting IP back to a hostname.

Most large receivers require forward-confirmed reverse DNS (FCrDNS):

  1. The sending IP has a PTR record, e.g. 203.0.113.10 → mail.domain.tld.
  2. That hostname resolves forward to the same IP: mail.domain.tld → 203.0.113.10.
  3. Ideally, the MTA's HELO/EHLO name (Postfix myhostname) is that same name.
dig +short -x 203.0.113.10       # PTR
dig +short A mail.domain.tld      # must return 203.0.113.10

PTR records are controlled by whoever owns the IP block (your ISP or cloud provider), not by your domain's DNS host. Residential connections almost never let you set one, and many cloud providers block outbound port 25 by default. This is the main reason so many small setups send outbound mail through a smart host (Gmail, Mailgun, Proton SMTP submission). Without a matching PTR and an IP with a sending reputation, mail is rejected or spam-foldered no matter how correctly the MTA is configured.

Relaying vs final delivery

There are two fundamentally different things an MTA can do with a message it accepts:

  • Final delivery: the MTA is authoritative for the recipient's domain (in Postfix, it's in mydestination, virtual_mailbox_domains or virtual_alias_domains) and hands the message to a mailbox or alias.
  • Relaying: the MTA is not authoritative for the recipient's domain but forwards the message toward it anyway.

Relaying is normal. Every outbound message from your users is relayed. But unrestricted relaying, accepting mail from anyone for any destination, makes a server an open relay. Open relays are found by scanners within hours, abused for spam, and blocklisted. Postfix's smtpd_relay_restrictions exists to say who may relay (trusted networks, authenticated users) and to reject everyone else with reject_unauth_destination.

Smart hosts and relay hosts

A smart host (Postfix calls it relayhost) is a single designated server that all outbound mail is handed to, instead of the MTA looking up each destination's MX itself. Your server authenticates to a provider that already has good IP reputation, correct PTR records and feedback-loop relationships, and lets it do final delivery.

 app / cron ──► local Postfix (null client) ──587 AUTH──► smart host ──25──► recipient MX

When you use a smart host, your domain's SPF must authorize the provider and your DKIM must be signed by it (or by you), or receivers will reject the mail even though the routing is perfect. See Email Authentication and Anti-Spam.

Split-horizon DNS

Larger or more careful setups sometimes run split-horizon DNS: internal clients resolve a mail hostname (or a domain's MX) to an internal address, while the internet resolves the same name to a public, internet-facing gateway. This is a DNS-server concern, not an MTA one. It explains why LAN-only mail setups sometimes need internal DNS zones or /etc/hosts entries rather than public DNS for internal routing. It also explains why an installer (Zimbra's, for example) can complain that "the MX doesn't point at this host" when it's resolving through the wrong view.

When debugging, always check which resolver the MTA is actually using (/etc/resolv.conf, or /var/spool/postfix/etc/resolv.conf for a chrooted Postfix) and query it directly:

dig @192.0.2.53 +short MX domain.tld

Quick DNS checklist for a mail domain

Record Example Purpose
MX domain.tld. MX 10 mail.domain.tld. Where inbound mail goes
A/AAAA mail.domain.tld. A 203.0.113.10 The MX host's address
PTR 10.113.0.203.in-addr.arpa. PTR mail.domain.tld. Reverse DNS for the sending IP (set by the IP owner)
SPF (TXT) domain.tld. TXT "v=spf1 mx include:_spf.provider.tld -all" Who may send as the domain
DKIM (TXT) sel1._domainkey.domain.tld. TXT "v=DKIM1; k=rsa; p=…" Public key for signatures
DMARC (TXT) _dmarc.domain.tld. TXT "v=DMARC1; p=quarantine; rua=mailto:…" Policy and reporting
MTA-STS / TLS-RPT _mta-sts.domain.tld, _smtp._tls.domain.tld Enforce TLS for inbound mail; receive TLS failure reports