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:

  1. Looks up the PTR for 203.0.113.10 and gets mail.example.com.
  2. Looks up the A record for mail.example.com and checks that it includes 203.0.113.10.
  3. 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 mail 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).