RE:NODE

App hosting11 min read

Reverse DNS for mail servers: PTR, FCrDNS and HELO

What a PTR record is, who controls it, how forward-confirmed reverse DNS and the HELO name must line up, how to check them, and what to do if you cannot set one.

0 readers

A mail server's IP address needs a reverse DNS record - a PTR - that turns the address back into a host name, and that host name must resolve forward to the same address. Large receivers check this on every connection, and Gmail's sender guidelines require it outright. The name should also be the one the server announces in its HELO/EHLO greeting. Get those three things in line - PTR, forward A record, HELO name - and you have removed one of the most common reasons a self-hosted server's mail is refused or filed as spam. The catch is that the PTR record is not in your domain's zone. It belongs to whoever owns the IP address, so you set it through your hosting provider, or not at all.

What a PTR record is#

Forward DNS maps names to addresses: mail.example.com has an A record of 203.0.113.25. Reverse DNS goes the other way, and it is done with an ordinary DNS lookup in a special part of the tree.

For IPv4, the address is written backwards, octet by octet, under in-addr.arpa:

the reverse zone entry for 203.0.113.25
25.113.0.203.in-addr.arpa.   3600  IN  PTR  mail.example.com.

The reversal is because DNS reads names from right to left - most general to most specific - while IP addresses are written from most general on the left. Reversing them lets the in-addr.arpa tree be delegated along network boundaries: the regional registry delegates 203.in-addr.arpa, then the block holder gets 113.0.203.in-addr.arpa, and so on.

For IPv6, the address is expanded to all 32 hexadecimal digits, reversed one nibble at a time, and placed under ip6.arpa. The PTR for 2001:db8::25 lives at a name 32 labels long ending in ...8.b.d.0.1.0.0.2.ip6.arpa. Nobody types these by hand; tools and provider panels generate them.

Who controls reverse DNS#

This is the part people find surprising. The reverse zone for an address belongs to whoever was allocated the address block - normally your hosting provider, ISP or cloud platform. You cannot create a PTR record in your own domain's DNS, because in-addr.arpa names are not in your domain.

How you get one set depends on the provider:

  • A field in the provider's control panel, common on VPS and cloud platforms - you enter the host name and the provider publishes the PTR, often after checking that your forward record already points at the address.
  • A support ticket, common for dedicated servers and smaller hosts.
  • Delegation of the reverse zone to your own nameservers, for organisations with their own address blocks. For blocks smaller than a /24, RFC 2317 describes a CNAME-based trick to delegate part of a reverse zone, which providers occasionally use.
  • Not available, for consumer connections, shared addresses and some container platforms. The address's PTR stays whatever the owner set, usually something generic like 203-0-113-25.static.provider.example.

Each address has one PTR in practice. Multiple PTR records for one address are technically possible and cause inconsistent results, so do not ask for them.

Forward-confirmed reverse DNS#

A PTR record on its own proves little: anyone who controls a reverse zone can make it say mail.google.com. So receivers check the round trip, called forward-confirmed reverse DNS (FCrDNS) or "full-circle" DNS:

  1. The receiver sees a connection from 203.0.113.25.
  2. It looks up the PTR: mail.example.com.
  3. It looks up the A record for mail.example.com: 203.0.113.25.
  4. The forward answer contains the original address, so the name is confirmed.
contains 203.0.113.25Incoming connectionfrom 203.0.113.25PTR lookup25.113.0.203.in-addr.arpamail.example.comA lookupmail.example.comConfirmedaddresses match
Forward-confirmed reverse DNS, checked on connect

If step 3 returns a different address, or nothing at all, FCrDNS fails. Since you control the A record and the provider controls the PTR, the round trip requires both halves: create mail.example.com pointing at the address in your zone, and have the provider set the PTR to mail.example.com. Many provider panels refuse to set a PTR until the forward record already exists, for exactly this reason.

The HELO name#

When your server connects to another mail server, the first thing it says after the banner is EHLO (or the older HELO) followed by its own name:

code
220 mx.receiver.example ESMTPEHLO mail.example.com250-mx.receiver.example Hello mail.example.com [203.0.113.25]

RFC 5321 requires that name to be a fully qualified domain name, or an address literal in square brackets if the host has no meaningful name. In practice, receivers and spam filters check that:

  • It is a real FQDN - not localhost, not a bare word like server1, not the container's random host name.
  • It resolves in DNS, ideally to the connecting address.
  • It matches, or is at least consistent with, the PTR name.

A mismatch between HELO and PTR is not fatal on its own at most receivers, but it adds spam score, and some filters reject an EHLO name that does not resolve at all. The clean arrangement is that all three names are the same: the HELO name, the PTR target, and an A record pointing back at the IP. In Stalwart, the HELO name comes from the server's configured host name, which is one more reason to set that once, correctly, at the start - see Stalwart mail server setup.

What receivers actually do with it#

Policies vary, and the large providers change them, but the general picture is consistent.

SituationTypical outcome
No PTR at allRefused by Gmail and many others, or heavy spam scoring
PTR exists, forward does not matchSpam scoring; refused by strict receivers
Generic PTR, e.g. 203-0-113-25.dyn.isp.exampleTreated like a home connection; spam folder or refused
PTR matches, HELO differsSmall scoring penalty at some filters
PTR, A and HELO all the same nameNo penalty - the expected state

Gmail's guidelines for anyone sending to personal Gmail accounts require that the sending IP has a valid PTR with a matching forward record; messages from IPs without one are rejected or rate-limited. Over IPv6, Gmail is stricter still about authentication, and a server with an IPv6 address but no IPv6 PTR is a common source of mysterious rejections. If your server has IPv6 connectivity and you cannot set a PTR for that address, configure it to send over IPv4 only.

Generic reverse names deserve special mention. Spam filters look for patterns like digits-and-dashes, dyn, dhcp, pool or cust in the PTR, because those mark residential and dynamic ranges. A PTR that technically confirms but looks like ip-203-0-113-25.provider.example still reads as "not a mail server". SpamAssassin, the oldest of the widely used filters, has rules named for exactly these cases - RDNS_NONE for a connection with no reverse name and RDNS_DYNAMIC for one that looks dynamic - and every other filter has its equivalents. Each adds a little to the score, and on a message that is borderline for other reasons, a little is enough.

Reverse DNS also feeds blocklists indirectly. Policy lists such as Spamhaus's PBL describe address ranges that their owners say should not send mail directly, and generic reverse names are part of how those ranges are identified. A server sending from such a range is treated as an infected home machine no matter how well its DNS is configured.

Several domains on one server#

The PTR does not need to match the domain in your From: address. A server hosting mail for example.com, example.org and a client's shop.example has one IP, one PTR and one HELO name - say mail.example.com - and that is fine. Receivers check that the sending host is a properly configured mail server, not that it is named after every domain it sends for. SPF, DKIM and DMARC tie each message to its own domain; SPF, DKIM and DMARC explained covers that link.

What you should not do is ask for the PTR to change per domain, or try to set several. One address, one name, consistent everywhere.

The reverse situation - several unrelated services sharing one address - is where reverse DNS gets awkward. An address that hosts websites, game servers and a mail server for different customers can still carry only one PTR, and it can only name one of them. That is part of why mail on shared addresses is usually sent through a relay, and why a mail server is better off as the only thing sending mail from its address. If a web application on the same address also sends mail directly, it shares the mail server's PTR and reputation, and any spam it sends is held against both.

Checking reverse DNS#

bash
# The PTR for an address$ dig +short -x 203.0.113.25mail.example.com.# The forward record for that name: should include the same address$ dig +short A mail.example.com203.0.113.25# The same for IPv6$ dig +short -x 2001:db8::25# The short form, which prints both directions$ host 203.0.113.2525.113.0.203.in-addr.arpa domain name pointer mail.example.com.

On Windows, Resolve-DnsName 203.0.113.25 returns the PTR, and nslookup 203.0.113.25 does the same.

To see what your server says in HELO, send a test message to an outside mailbox and read the topmost Received: header added by the receiver - it records the HELO name and the reverse lookup side by side:

code
Received: from mail.example.com (mail.example.com. [203.0.113.25])        by mx.google.com with ESMTPS id ...

The first mail.example.com is your HELO; the one in brackets is what the receiver found in reverse DNS. If they agree and the address is right, you are done. If the bracket shows something like unknown or a generic provider name, the PTR is missing or not set to your host.

Requesting a PTR and fixing the usual mistakes#

When your provider does offer reverse DNS, the request is short, but the order matters.

  1. Pick the host name. Use the name your mail server will announce, normally mail.example.com. Not the bare domain, and not a name that already points somewhere else.
  2. Create the forward record first. Add mail.example.com as an A record (and AAAA if you send over IPv6) pointing at the server's address, and check it from outside with dig @1.1.1.1 +short A mail.example.com. Providers that validate requests will refuse a PTR whose forward record does not exist yet.
  3. Ask for the PTR, in the panel field or by ticket, naming the exact address and the exact host name. For IPv6, give the full address the server sends from - a server may have a whole range and use only one.
  4. Set the mail server's host name to the same name, so the HELO matches.
  5. Wait out the TTL and check with dig -x, then send a test to an outside mailbox and read the Received: header.

The mistakes that turn up afterwards are few and repetitive:

  • Trailing dot or typo. A PTR of mail.example.com.example.com or mial.example.com confirms nothing. Read the dig -x answer letter by letter.
  • The forward record changed later. Someone moves mail.example.com to a new address for a migration and forgets that the old server is still sending. FCrDNS breaks on the old one silently.
  • The server sends from a different address than expected. A machine with several addresses, or a NAT in front of a container, may connect out from an address other than the one you asked about. The Received: header at the recipient shows which address actually connected; set the PTR on that one.
  • IPv6 forgotten. The IPv4 setup is perfect, the server prefers IPv6 when the receiver offers it, and the IPv6 address has no PTR. Either add one or restrict outbound mail to IPv4.
  • The HELO name is the container's host name. Some software defaults to the system host name, which in a container is a random string. Set it explicitly.

When you cannot set a PTR#

This is common, and it is not the end of self-hosted mail.

  1. Send through a relay. Your server hands outbound mail to a smarthost on port 587 or 465, and the recipient sees the relay's IPs, which have correct reverse DNS and established reputation. Your DKIM signature still identifies your domain. SMTP relay for outgoing mail covers the setup.
  2. Receive directly anyway. Reverse DNS matters for the sending side. Mail delivered to you does not depend on your server's PTR, so inbound on port 25 works regardless.
  3. Set the HELO name to something that resolves even if the PTR is generic. It will not fix FCrDNS, but it removes the second penalty.

Option 1 is the standard answer, and it also deals with outbound port blocks at the same time - see port 25 and outbound mail blocks.

FAQ#

Do I create the PTR record in my domain's DNS?

No. Reverse DNS for an address belongs to whoever owns the address, usually your hosting provider. You create the forward A record in your zone and ask the provider to set the PTR for the IP.

Does the PTR have to match my email domain?

No. It has to be a real host name that resolves back to the same IP. One server can send for many domains under a single PTR such as mail.example.com.

How long does a PTR change take to work?

Like any DNS change, as long as the old record's TTL, which providers often set to a day. Ask for it well before you start sending, not on the day.

My PTR is correct but Gmail still rejects mail. Why?

Check IPv6. If the server has an IPv6 address and sends over it, that address needs its own PTR and matching AAAA record. Then check SPF, DKIM and DMARC - reverse DNS is only one of the requirements. Why email goes to spam has the full list.

Is reverse DNS needed to receive mail?

Not for your server to receive. Senders deliver to your MX regardless of your PTR. Reverse DNS is about how receivers judge mail you send.


Comments

Completely anonymous: no account, no email, no cookie. We store the name you type, the text and the time - nothing else. Links are limited and markup is not rendered.

0/2000