Reverse DNS for email comes down to three names agreeing: your sending IP has a PTR record pointing to a hostname, that hostname's A record points back to the same IP (forward-confirmed reverse DNS, or FCrDNS), and your mail server says that same hostname in HELO. Receivers treat mail from an IP with no PTR, or a generic one, as suspicious, and some refuse it. You set the PTR with whoever owns the IP, which for a VPS means your provider's control panel.
This is one of the first things we check on any self-hosted email server, because it is invisible until something breaks. We use mail.example.com and the documentation IP 203.0.113.10 below.
How receivers use reverse DNS
When your server connects to deliver a message, the receiver knows only the IP address. It then:
- Looks up the PTR for
203.0.113.10and getsmail.example.com. - Looks up the A record for
mail.example.comand checks that it includes203.0.113.10. - Compares that with the name your server gave in
EHLO.
| Check | Good | Bad |
|---|---|---|
| PTR exists | mail.example.com |
none (NXDOMAIN) |
| PTR is specific | mail.example.com |
203-0-113-10.provider.example |
| Forward-confirms | A record = 203.0.113.10 | A record points elsewhere or does not exist |
| HELO matches | EHLO mail.example.com |
EHLO localhost or EHLO ubuntu |
A generic provider name like vps-1234.provider.example technically exists and may even forward-confirm, but it looks like a host that was never configured for mail. Google's sender guidelines ask that sending IPs have valid reverse DNS, and other receivers check it too.
Why receivers care about reverse DNS
A lot of spam comes from machines that were never meant to be mail servers: infected home computers, misconfigured cloud instances, throwaway VPSes. Those hosts usually have no PTR at all, or the generic one their network assigned. A legitimate mail server, by contrast, has an operator who asked the IP owner to set a specific name and made that name resolve back.
So reverse DNS is a cheap signal for receivers. It does not prove you are trustworthy, since anyone with a VPS can set a PTR, but missing or mismatched reverse DNS is a strong hint that nobody is looking after the server. Some receivers reject such connections outright; others add to the spam score. Either way, it is free to get right.
You can see the same check from the receiving side. When Postfix accepts a connection from an IP whose reverse DNS does not forward-confirm, it logs the client as unknown[203.0.113.99] instead of a hostname.
Step 1: Pick the hostname
Use a hostname under the domain you send from, for example mail.example.com. If you send for several domains from one IP, pick one of them; the PTR can only hold one name per IP. We run two domains on two IPs, so each IP has its own PTR for its own domain's mail host.
Keep this hostname dedicated to mail rather than reusing your website's name. Because receivers may also check SPF for the HELO name, publish a small SPF record on it too. We use v=spf1 a -all on each mail host, which authorizes exactly the IP in its own A record; how to set up an SPF record explains why.
Step 2: Create the A record
At your DNS host:
| Type | Host | Value |
|---|---|---|
| A | 203.0.113.10 |
Wait until it resolves:
dig +short A mail.example.com
Some providers refuse to set a PTR to a name that does not resolve yet, so do this first.
Step 3: Set the PTR at your VPS provider
In your provider's panel, find the IP address settings (often called "reverse DNS", "rDNS" or "PTR") and set 203.0.113.10 to mail.example.com. Some providers need a trailing dot (mail.example.com.); the panel will usually say. A few handle it by support ticket.
You cannot set this at your domain registrar or DNS host. The reverse zone for the IP (10.113.0.203.in-addr.arpa) belongs to the network that owns the IP.
Step 4: Make the server use the same name
In Postfix, the HELO name comes from myhostname unless overridden:
sudo hostnamectl set-hostname mail.example.com
sudo postconf -e 'myhostname = mail.example.com'
sudo postconf -e 'smtpd_banner = $myhostname ESMTP'
sudo systemctl reload postfix
postconf myhostname smtp_helo_name
smtp_helo_name defaults to $myhostname, so it should show the same value.
Several IPs on one server
If Postfix sends from more than one IP, each outbound transport needs its own bind address and HELO name. This is what we run in master.cf to send two domains from two IPs:
smtp-brand unix - - y - - smtp
-o smtp_bind_address=203.0.113.10
-o smtp_helo_name=mail.example.com
smtp-outreach unix - - y - - smtp
-o smtp_bind_address=203.0.113.11
-o smtp_helo_name=mail.example.net
sender_dependent_default_transport_maps in main.cf then picks the transport by sender domain. Each IP gets its own PTR, A record and matching HELO name.
Step 5: Decide what to do about IPv6
Many VPSes come with an IPv6 address. If Postfix can use IPv6 and that address has no PTR, some messages will go out over IPv6 and fail reverse DNS checks, while the IPv4 ones pass. That inconsistency is confusing to debug.
Either set a PTR, A/AAAA records and SPF for the IPv6 address too, or keep mail on IPv4. We run IPv4 only:
sudo postconf -e 'inet_protocols = ipv4'
sudo systemctl restart postfix
Troubleshooting reverse DNS problems
| Symptom | Likely cause | Fix |
|---|---|---|
dig -x returns nothing |
No PTR set | Set it in the VPS provider's panel |
dig -x returns the provider's generic name |
PTR never changed, or change not saved | Set it again; some panels need the A record to exist first |
| PTR is right, port25 says iprev fail | A record missing or pointing elsewhere | Point mail.example.com at the sending IP |
| Some messages pass, some fail | Mail sometimes leaves over IPv6 | Add IPv6 PTR, or set inet_protocols = ipv4 |
| Correct when you check, wrong in a report from an hour ago | Cached old record | Wait for the TTL to expire and retest |
| Second domain's mail shows the first domain's HELO | Both domains use the same transport | Give each IP its own transport with smtp_helo_name |
The Received header a receiver adds is the quickest way to see what it saw. Gmail's looks like this when everything is right:
Received: from mail.example.com (mail.example.com. [203.0.113.10])
by mx.google.com with ESMTPS id ...
The first name is your HELO; the name in parentheses is what reverse DNS returned for the IP. They should match.
Reverse DNS with a hosted provider
On a provider's shared IPs, reverse DNS points to the provider's own hostnames, and that is fine: receivers judge the provider's infrastructure, and your domain is authenticated by DKIM and SPF. With a dedicated IP from a provider, check whether you can set a custom PTR under your own domain. It is not required, but it keeps the whole chain under your name. The trade-offs between the two are in shared vs dedicated IPs.
Common mistakes
- Setting the PTR in the wrong place. Creating a "PTR record" in your domain's DNS panel does nothing for outbound mail. It must be set by the IP owner.
- PTR without a matching A record. The PTR says
mail.example.com, but there is no A record, or it points to your web server. That fails FCrDNS. - HELO left as the default. A server still introducing itself with the image's default hostname looks unconfigured.
- Forgetting IPv6. Covered above. It is the most common "it works sometimes" cause we see.
- Trusting a stale resolver. After we set one of our PTRs, a cached lookup kept showing the old value for a while. Query the authoritative path, or wait for the TTL, before assuming the change failed.
- Several PTR records for one IP. Publish exactly one. With more than one, receivers may check any of them, and the result becomes unpredictable.
- Thinking the PTR must match every From domain. It does not. One IP sending for several domains needs only one PTR, matching its HELO name. Domain authentication is SPF, DKIM and DMARC's job.
- Changing the PTR to a web hostname. If the IP also serves websites, keep the PTR on the mail hostname. Web traffic does not care about reverse DNS.
How to verify it worked
Check both directions from any machine:
dig +short -x 203.0.113.10
dig +short A mail.example.com
The first should return mail.example.com. and the second 203.0.113.10. Check the banner and EHLO from outside:
swaks --to postmaster@example.com --server mail.example.com --quit-after EHLO
Then send a real message to port25's verifier. Its report includes an iprev result, and on our servers it reads iprev check: pass:
swaks --to check-auth@verifier.port25.com --from hello@example.com \
--server mail.example.com --port 587 --tls \
--auth LOGIN --auth-user hello@example.com
mail-tester.com also flags missing or mismatched reverse DNS. If reverse DNS is right and mail still lands in spam, the next places to look are in why are my emails going to spam and, for a new server, IP warm-up.
If you would like someone to check PTR, FCrDNS, SPF, DKIM and DMARC for you, that is part of our Deliverability Fix (see pricing).