MX (Mail Exchanger) records are the DNS entries that tell the internet where to deliver email for your domain. Change them — or let someone else change them — and inbound email stops reaching you. Senders receive bounce messages or silent delivery failures. Business email disappears into a void. The problem can go undetected for hours or days before someone notices that expected messages never arrived.
This guide covers how to check MX records manually, what causes unexpected MX record changes, and how continuous MX record monitoring catches changes before they become deliverability disasters.
Three tools are available on any Linux, macOS, or Windows system:
# Query MX records for a domain
dig MX example.com
# Short output — just the records
dig MX example.com +short
# Query a specific DNS server (e.g., Google's 8.8.8.8)
dig MX example.com @8.8.8.8 +short
Sample output:
10 aspmx.l.google.com.
20 alt1.aspmx.l.google.com.
20 alt2.aspmx.l.google.com.
30 alt3.aspmx.l.google.com.
30 alt4.aspmx.l.google.com.
The number before each hostname is the MX priority. Lower numbers are tried first. Multiple records with the same priority are used round-robin.
# Windows, macOS, Linux
nslookup -type=MX example.com
# Query a specific resolver
nslookup -type=MX example.com 8.8.8.8
host -t MX example.com
MX records control inbound mail routing. When they change unexpectedly, the impact depends on how they changed:
If MX records are accidentally deleted, sending servers fall back to the domain's A record (if any) or return a bounce. Most senders get an SMTP error like 550 5.1.2 Bad destination mailbox address or simply time out. Inbound mail stops flowing immediately.
If MX records are changed to point to a non-existent or unreachable server, senders queue mail and retry for 4–5 days before giving up. You may not notice for hours — email appears to be working because outbound mail is unaffected, but inbound mail is silently queuing at senders' MTAs.
In a DNS hijacking or domain takeover scenario, MX records can be changed to route inbound email to an attacker-controlled mail server. This enables email interception and account takeover at scale. The attack is silent — senders successfully deliver mail, it just doesn't reach you.
Migrating from one email provider to another (e.g., self-hosted to Google Workspace, or Outlook to a new provider) requires changing MX records. A misconfigured migration — wrong priority values, old records left in place, TTL not lowered before the change — causes split delivery or complete loss during the transition window.
MX records can appear different depending on which DNS resolver you query, due to caching or split-horizon configurations. Check multiple resolvers to detect inconsistencies:
#!/bin/bash
# check-mx-resolvers.sh — query MX from multiple resolvers and compare
DOMAIN="example.com"
RESOLVERS=("8.8.8.8" "1.1.1.1" "9.9.9.9" "208.67.222.222")
echo "MX records for $DOMAIN:"
echo ""
for resolver in "${RESOLVERS[@]}"; do
echo "--- Resolver $resolver ---"
dig MX "$DOMAIN" @"$resolver" +short | sort
echo ""
done
If the output is consistent across resolvers, the change has propagated fully. If resolvers disagree, propagation is still in progress (or a split-horizon configuration is intentional).
A simple approach: snapshot current MX records and alert when they change.
#!/bin/bash
# monitor-mx.sh — alert when MX records change
DOMAIN="example.com"
SNAPSHOT_FILE="/var/lib/dns-monitor/mx-${DOMAIN}.txt"
ALERT_EMAIL="ops@example.com"
mkdir -p "$(dirname "$SNAPSHOT_FILE")"
# Get current MX records (sorted for consistent comparison)
current=$(dig MX "$DOMAIN" +short @8.8.8.8 | sort)
if [ ! -f "$SNAPSHOT_FILE" ]; then
# First run — create baseline
echo "$current" > "$SNAPSHOT_FILE"
echo "Baseline created for $DOMAIN MX records"
exit 0
fi
previous=$(cat "$SNAPSHOT_FILE")
if [ "$current" != "$previous" ]; then
# Records changed — send alert
{
echo "MX records changed for $DOMAIN"
echo ""
echo "Previous:"
echo "$previous"
echo ""
echo "Current:"
echo "$current"
echo ""
echo "Time: $(date)"
} | mail -s "ALERT: MX record change detected for $DOMAIN" "$ALERT_EMAIL"
# Update snapshot
echo "$current" > "$SNAPSHOT_FILE"
fi
Run this via cron every 5–15 minutes for near-real-time detection:
# Check MX records every 10 minutes
*/10 * * * * /usr/local/bin/monitor-mx.sh
When auditing MX records, check more than just the hostnames. A correct MX configuration requires:
aspmx.l.google.com for Google Workspace)# Verify MX host resolves
host $(dig MX example.com +short @8.8.8.8 | awk '{print $2}' | head -1)
# Check SPF record
dig TXT example.com +short | grep "spf"
terraform apply that recreates a DNS zone replaces all records; if MX records aren't in the Terraform state, they're deletedLook up current MX records for any domain instantly — see all records, priorities, and resolve status with no signup required.
Check MX records → Get change alerts →DNSWatch monitors MX records (and all other DNS record types) for your domains on a continuous schedule. When records change, you get an immediate alert with the before and after values — so you know exactly what changed and when, whether it was a planned migration or an unauthorized modification.
No script to maintain. No cron job to watch. Monitoring runs from external infrastructure independent of your DNS management environment.
DNSWatch monitors MX, A, CNAME, TXT, and NS records for your domains and alerts you the moment anything changes.
Join the DNSWatch waitlist → Free DNS checker →