
What is an MX record and how does email routing work?
An MX (Mail Exchanger) record is a DNS record that tells other mail servers which server accepts email for your domain. When someone sends a message to you@example.com, their mail server looks up the MX records for example.com, picks the server with the lowest priority number, and delivers the message to it over SMTP. Without a correct MX record, mail sent to your domain has nowhere to go and will eventually bounce.
MX records are one of the oldest record types in DNS, and they're also one of the easiest to get subtly wrong. In this article you'll learn what an MX record contains, how sending servers use it step by step, how priority and failover really work, the rules MX targets must follow, how to check your records from the command line, and the mistakes that cause lost or delayed email.
What an MX Record Looks Like
An MX record has two pieces of data: a priority (also called preference) and a target hostname. In a zone file it looks like this:
example.com. 3600 IN MX 10 mail1.example.com.
example.com. 3600 IN MX 20 mail2.example.com.
Here's what each part means:
- example.com.: The domain the record applies to. Mail addressed to anything
@example.comuses these records. - 3600: The TTL (time to live) in seconds. Resolvers can cache the answer for one hour.
- IN: The class, which is always
IN(internet) in practice. - MX: The record type.
- 10 / 20: The priority. Lower numbers are preferred. A sender tries priority 10 before priority 20.
- mail1.example.com.: The hostname of the mail server. It must have its own A and/or AAAA record.
The priority is a 16-bit number, so it can range from 0 to 65535. The actual values don't matter, only their order. 10 and 20 behave exactly the same as 1 and 2. People tend to use gaps of 10 so they can slot a new server in between later without renumbering everything.
How Email Routing Works Step by Step
Email delivery between servers follows a process defined in the SMTP standard (RFC 5321). When a user at another company sends a message to alice@example.com, this is what happens:
- The message is submitted: The sender's email client hands the message to their own outgoing mail server (for example, Gmail or Microsoft 365).
- The domain is extracted: The sending server takes everything after the
@, in this caseexample.com. - An MX lookup is made: The sending server asks its DNS resolver for the MX records of
example.com. - Targets are sorted: The server sorts the returned hosts by priority, lowest first. Hosts with the same priority are tried in random order, which spreads the load.
- The target is resolved: The server looks up the A or AAAA record of the chosen MX host to get an IP address.
- An SMTP connection is opened: The sending server connects to that IP on TCP port 25, usually upgrades the connection with STARTTLS, and transfers the message.
- Fallback on failure: If the connection fails or the server returns a temporary error, the sender moves on to the next host in the list. If every host fails, the message is queued and retried for several days before a bounce is generated.
The receiving server then applies its own checks, such as spam filtering and SPF, DKIM and DMARC validation, before putting the message in Alice's mailbox.
What If There's No MX Record?
If a domain has no MX record at all, SMTP falls back to the domain's own A or AAAA record. This is called the implicit MX rule. A sender will try to deliver mail for example.com directly to the IP address of example.com, which is usually a web server that doesn't accept mail.
That fallback is why domains that never send or receive email should publish a null MX record (RFC 7505):
example.com. 3600 IN MX 0 .
A single dot as the target, with priority 0, means "this domain does not accept email". Senders that see it fail immediately with a clear error instead of queuing messages for days or trying your web server.
Priority, Failover and Load Balancing
MX priority gives you two useful behaviours: failover and load spreading.
Failover With Different Priorities
example.com. 3600 IN MX 10 mx1.example.com.
example.com. 3600 IN MX 20 mx2.example.com.
Senders always try mx1 first. They only use mx2 when mx1 is unreachable or returns a temporary failure. This is the classic primary and backup setup.
Load Spreading With Equal Priorities
example.com. 3600 IN MX 10 mx1.example.com.
example.com. 3600 IN MX 10 mx2.example.com.
When two records share the same priority, senders choose between them randomly. Over many messages, the load is split roughly evenly. Large providers publish several hosts at the same priority for exactly this reason.
A Note on Backup MX Servers
Running a separate backup MX used to be common practice, but it's less useful today and can cause problems:
- Spam bypass: Spammers deliberately target the lowest-priority server because backup servers often have weaker filtering.
- Backscatter: A backup server that accepts mail for invalid addresses has to bounce it later, sending bounces to forged sender addresses.
- Senders already retry: Legitimate mail servers queue undeliverable messages and retry for days, so a short outage on your primary rarely loses mail.
If you use a hosted email provider such as Google Workspace or Microsoft 365, you shouldn't add your own backup MX. Their infrastructure is already redundant behind the hostnames they give you.
Rules for MX Targets
The target of an MX record has strict requirements, and breaking them causes delivery failures that can be hard to spot.
| Rule | Why it matters |
|---|---|
| The target must be a hostname, not an IP address | MX 10 192.0.2.25 is invalid. Senders expect a name and will reject or misinterpret an IP. |
| The target must not be a CNAME | RFC 2181 forbids MX targets that are aliases. Many servers tolerate it, but some reject it. |
| The target must have an A or AAAA record | Without an address record, senders can't connect. |
| The target should have a matching PTR record | Reverse DNS matters mostly for sending, but many receivers check it on inbound servers too. |
| The domain should not be a CNAME | If example.com is a CNAME, it can't hold MX records alongside it. |
The CNAME rule is the one people break most often. If you want a friendly name such as mail.example.com to point at your provider, point the MX record directly at the provider's hostname instead:
; Wrong: the MX target is an alias
example.com. IN MX 10 mail.example.com.
mail.example.com. IN CNAME mx.provider.example.net.
; Right: point the MX straight at the real host
example.com. IN MX 10 mx.provider.example.net.
Checking MX Records From the Command Line
You can look up any domain's MX records with standard tools.
Using dig
dig example.com MX +noall +answer
Sample output:
example.com. 3600 IN MX 10 mx1.example.com.
example.com. 3600 IN MX 20 mx2.example.com.
Then check that each target resolves:
dig mx1.example.com A +short
dig mx1.example.com AAAA +short
192.0.2.25
2001:db8::25
To see what the authoritative nameserver says rather than a cached answer, query it directly:
dig @ns1.example.com example.com MX +norecurse
Using nslookup
On Windows, or anywhere dig isn't installed:
nslookup -type=mx example.com
Server: 192.0.2.53
Address: 192.0.2.53#53
Non-authoritative answer:
example.com mail exchanger = 10 mx1.example.com.
example.com mail exchanger = 20 mx2.example.com.
Using PowerShell
Resolve-DnsName -Name example.com -Type MX | Sort-Object Preference
Name Type TTL Section NameExchange Preference
---- ---- --- ------- ------------ ----------
example.com MX 3600 Answer mx1.example.com 10
example.com MX 3600 Answer mx2.example.com 20
Testing the SMTP Connection
DNS only tells you where mail should go. To confirm the server actually accepts connections and offers TLS, connect to it on port 25:
openssl s_client -starttls smtp -connect mx1.example.com:25 -crlf -quiet
If it works you'll see the certificate chain followed by the server's SMTP banner, such as 250 mx1.example.com. Note that many home and cloud networks block outbound port 25, so run this test from a server that's allowed to send mail.
Simulating MX Selection in Python
It can help to see how a sending server orders MX hosts. This short script uses the dnspython library to fetch MX records and print them in the order a sender would try them, shuffling hosts that share a priority:
import random
import sys
import dns.resolver
def mx_order(domain):
answers = dns.resolver.resolve(domain, "MX")
by_priority = {}
for rdata in answers:
by_priority.setdefault(rdata.preference, []).append(
str(rdata.exchange).rstrip(".")
)
order = []
for priority in sorted(by_priority):
hosts = by_priority[priority]
random.shuffle(hosts)
order.extend((priority, host) for host in hosts)
return order
if __name__ == "__main__":
domain = sys.argv[1] if len(sys.argv) > 1 else "example.com"
for priority, host in mx_order(domain):
if host == "":
print("Null MX: this domain does not accept email")
break
addresses = []
for rtype in ("A", "AAAA"):
try:
addresses += [r.to_text() for r in dns.resolver.resolve(host, rtype)]
except (dns.resolver.NoAnswer, dns.resolver.NXDOMAIN):
pass
print(f"{priority:>5} {host:<30} {', '.join(addresses) or 'NO ADDRESS'}")
Install the dependency and run it:
pip install dnspython
python mx_order.py example.com
10 mx1.example.com 192.0.2.25, 2001:db8::25
20 mx2.example.com 198.51.100.25
A line showing NO ADDRESS means the MX target has no A or AAAA record, which will break delivery to that host.
MX Records for Popular Email Providers
Each hosted email service gives you its own MX values. Always copy them from your provider's admin console, because they differ per customer and change over time. As a guide to what to expect:
- Google Workspace: New setups use a single record,
1 smtp.google.com. Older domains may still have the previous five-record set (aspmx.l.google.comand its alternates), which continues to work. - Microsoft 365: A single record with priority 0 pointing at a tenant-specific hostname, such as
example-com.mail.protection.outlook.com. Newer tenants may be given a hostname undermx.microsoftinstead. - Self-hosted servers: Your own hostname, such as
mail.example.com, with A, AAAA and PTR records you control.
When you switch providers, remove the old provider's MX records. Leaving them in place with a higher priority number means some mail can still trickle to the old system whenever the new one is briefly unreachable.
MX Records for Subdomains
MX records apply to the exact name they're published on, not to subdomains. If you want to receive mail at support@help.example.com, you need MX records on help.example.com itself:
help.example.com. 3600 IN MX 10 inbound.ticketing.example.net.
This is common with helpdesk tools, marketing platforms and transactional email services that handle replies on a dedicated subdomain. It also keeps those services completely separate from your main mailbox provider.
Securing Mail Delivery Beyond MX
Plain MX lookups have a weakness: an attacker who can tamper with DNS could swap your MX target, and STARTTLS on port 25 is opportunistic, so a sender will usually fall back to unencrypted delivery if TLS fails. Two standards address this:
- MTA-STS (RFC 8461): You publish a policy over HTTPS listing your valid MX hostnames and requiring TLS. Supporting senders, including Gmail and Microsoft, refuse to deliver to anything else.
- DANE for SMTP (RFC 7672): You publish TLSA records for your MX hosts in a DNSSEC-signed zone, so senders can verify your server's certificate through DNS.
Both build on correct MX records, so get those right first.
Common MX Record Mistakes
Most email routing problems come down to a handful of mistakes:
- Pointing MX at an IP address: The target must be a hostname with its own A or AAAA record.
- Using a CNAME as the target: Point straight at the real host instead.
- Leaving old provider records behind: Lower-priority leftovers can quietly receive some of your mail.
- Putting a CNAME on the root domain: Some DNS providers let you do it, but it hides your MX records and breaks mail. Use an A record, or an ALIAS-style record if your provider offers one.
- Forgetting the trailing dot in zone files: In BIND-style files,
mx1.example.comwithout a dot becomesmx1.example.com.example.com.. Web control panels usually handle this for you. - Changing MX with a long TTL: Lower the TTL a day or so before a planned switch, so senders pick up the new value quickly.
- Having no MX on a domain that doesn't use email: Publish a null MX so senders fail fast instead of trying your web server.
FAQ: MX Records
Lower wins. A sender tries the host with the smallest priority number first and only moves to higher numbers if that host is unreachable or returns a temporary error.
No. The target must be a hostname that has its own A or AAAA record. If you only have an IP address, create a name such as mail.example.com with an A record and point the MX at that name.
Yes. Multiple records with different priorities give you failover, and records with the same priority spread the load between hosts. Hosted providers may give you one record or several depending on their setup.
Not directly. MX records control where incoming mail is delivered. Outgoing mail depends on your SPF, DKIM and DMARC records and your sending server's reputation, although some receivers do check that the sending domain has valid MX records.
Senders either can't connect and keep retrying for several days before bouncing the message, or they deliver to the wrong server. Fix the record and lower its TTL in future so corrections take effect faster.
A null MX is an MX record with priority 0 and a target of a single dot. It tells senders the domain accepts no email, so they reject messages immediately rather than queuing them or falling back to the domain's A record.
It depends on the TTL of the old record. Resolvers that cached it will keep using the old value until it expires. With a TTL of 3600, most senders see the change within an hour.
Conclusion
An MX record is a simple pointer with a priority attached, but it decides where every message sent to your domain ends up. Senders look it up, sort the hosts by priority, resolve the chosen host to an address and deliver over SMTP, falling back to the next host if something goes wrong.
Keep your MX targets as real hostnames with valid address records, remove leftovers when you change providers, and publish a null MX on domains that never receive mail. Check your records with dig or Resolve-DnsName after every change, and email routing will be one part of your DNS you rarely have to think about.


