For an MX record setup, add a record of type MX on @ with a priority such as 10 and a hostname as the target, for example mail.example.com. That hostname needs its own A record, and AAAA if IPv6 works, pointing at the mail server. For mail that actually gets delivered you also need SPF, DKIM, DMARC and a matching PTR record.
Adding the MX record takes a minute. Getting mail into Gmail and Outlook inboxes afterwards depends on five more records, and one of them doesn’t even live in your zone. If you run Postfix on a VPS, set up all six together.
What the MX record does
The MX (mail exchanger) record tells other mail servers where to deliver mail for @example.com. It points at a hostname, never an IP, and carries a priority:
$ORIGIN example.com.
@ 3600 IN MX 10 mail.example.com.
mail 3600 IN A 192.0.2.25
mail 3600 IN AAAA 2001:db8:10::25
A sending server looks up MX example.com, gets mail.example.com, resolves that name and connects on port 25. Two rules from RFC 2181 and RFC 5321 are firm: the target is a name with its own A or AAAA record, and it isn’t a CNAME. The reasoning is in CNAME vs A record.
Priority with several MX records
| Record | Meaning |
|---|---|
MX 10 mail.example.com. | Primary server |
MX 20 backup.example.net. | Used only when 10 is unreachable |
MX 10 mx1.example.com. + MX 10 mx2.example.com. | Equal preference, load is shared |
MX 0 . | Null MX: domain accepts no mail (RFC 7505) |
A single VPS rarely needs a backup MX. Senders don’t bounce immediately when your server is down. They queue and retry for days. A poorly maintained backup MX without spam filtering, on the other hand, is a well-known way in for spam.
Publish a null MX on every domain that receives no mail. Without any MX, senders fall back to the A record and try to deliver to your web server.
MX record setup: every record Postfix needs
For your own mail server the complete set looks like this:
$ORIGIN example.com.
@ 3600 IN MX 10 mail.example.com.
mail 3600 IN A 192.0.2.25
mail 3600 IN AAAA 2001:db8:10::25
@ 3600 IN TXT "v=spf1 mx -all"
mail._domainkey 3600 IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqh...IDAQAB"
_dmarc 3600 IN TXT "v=DMARC1; p=none; rua=mailto:[email protected]"
SPF lists who may send for the domain. mx allows the hosts from the MX record and -all rejects everyone else. If a newsletter service also sends as you, add its include:. A domain may have only one SPF record.
DKIM signs outgoing mail. Generate the key on the server, with OpenDKIM for instance via opendkim-genkey -s mail -d example.com. The part before ._domainkey is the selector and must match your signing configuration. Some panels split long keys into several quoted strings, which is fine.
DMARC tells receivers what to do when SPF or DKIM fail and where to send reports. Start with p=none, read the reports for a few weeks, then move to quarantine or reject. Since 2024, Gmail and Yahoo require at least SPF or DKIM from all senders, and DMARC as well from bulk senders.
At betadomain you add all of these in the customer area under the domain’s DNS records.
The record outside your zone: PTR
Many receivers check that your mail server’s IP has a reverse DNS entry that matches its hostname. The PTR record lives in your hosting provider’s zone, not yours, and you set it in their panel. Without it, mail lands in spam or is rejected outright. The how-to is in reverse DNS and PTR records.
Postfix’s myhostname should match:
postconf myhostname
myhostname = mail.example.com
The HELO name, the PTR for the IP and the A record of mail.example.com should all agree.
Check MX and mail DNS
dig example.com MX +short
dig mail.example.com A +short
dig example.com TXT +short | grep spf
dig mail._domainkey.example.com TXT +short
dig _dmarc.example.com TXT +short
dig -x 192.0.2.25 +short
Then test port 25 and STARTTLS from outside:
openssl s_client -starttls smtp -connect mail.example.com:25 -servername mail.example.com
If that fails from another machine while Postfix is running, check the firewall. In the other direction, some VPS providers block outbound port 25 for new accounts until you ask support to lift it. You’ll see it as messages stuck in postqueue -p with connection timeouts.
A certificate for the mail hostname
Senders encrypt with STARTTLS when you offer it, and a valid certificate for mail.example.com avoids client warnings on IMAP and submission. If nginx already runs on the server, get one with certbot and point Postfix at it:
certbot certonly --nginx -d mail.example.com
postconf -e 'smtpd_tls_cert_file = /etc/letsencrypt/live/mail.example.com/fullchain.pem'
postconf -e 'smtpd_tls_key_file = /etc/letsencrypt/live/mail.example.com/privkey.pem'
systemctl reload postfix
Postfix and Dovecot have to reload after each renewal, easiest with a --deploy-hook.
Four mistakes behind lost mail
- MX pointing at the bare domain (
MX 10 example.com.). It works until you move the website, and the mail moves with it. A separatemailname decouples the two. - Old MX records left behind. After switching from your host’s mailboxes to your own server, their MX records often remain with a lower priority.
dig MXshows them. - Two SPF records. One from the old host, one from you. RFC 7208 treats that as a permanent error, as if the domain had no SPF at all. Merge them.
- AAAA without an IPv6 PTR. Give
mailan AAAA record and Postfix delivers over IPv6, where Gmail rejects senders without PTR. See the AAAA record guide.
Switching MX without losing mail
When you change mail servers, lower the MX TTL first, as described in the DNS TTL guide. Keep the old server accepting mail until the old TTL has passed, then copy what arrived there with imapsync. Senders that hit a temporary failure in between retry later.
Set the PTR at your provider, send a test message to a Gmail account and look for the SPF, DKIM and DMARC lines under “Show original”. If you want a separate domain just for mail, you can find one at betadomain. An .email domain is €29.99 a year and a .com for the mail host €14.99.
Step by step
- Create an A record for the mail hostPoint mail.example.com at the mail server with an A record, plus AAAA if IPv6 is configured.
- Add the MX recordOn @, create an MX record with priority 10 and target mail.example.com, and remove old MX records.
- Publish SPFAdd a TXT record on @ with v=spf1 mx -all so only the MX host may send for the domain.
- Set up DKIMGenerate a key with OpenDKIM or rspamd and publish the public part as TXT at selector._domainkey.
- Publish DMARCAdd a TXT record at _dmarc with v=DMARC1; p=none; rua=mailto:... and tighten the policy after a few weeks of reports.
- Set PTR and testSet the reverse DNS of the server IP to mail.example.com at your hosting provider and check with dig MX, dig -x and a test message.
Found your domain? You can check and register it directly at compare domain prices – yearly price from €2.99.
FAQ
Can an MX record point directly to an IP address?
No. The MX target must be a hostname that has its own A or AAAA record. Panels that accept an IP usually create a helper name behind the scenes or store an invalid record.
What does the number before the MX target mean?
It's the preference. Senders try the lowest number first. Records with equal numbers share the load, and higher numbers act as backups.
What happens if a domain has no MX record?
Under RFC 5321, senders fall back to the domain's A or AAAA record. If a domain should never receive mail, publish a null MX as defined in RFC 7505: priority 0 and a single dot as the target.
How long does a new MX record take to work?
As long as the old MX record's TTL. Sending servers that reach the old server in the meantime and get a temporary error keep retrying for days, so short transitions rarely lose mail.