Short answer: reverse DNS (rDNS) turns an IP address back into a host name, using a PTR record. The PTR record is set by whoever holds the IP address block, which for a rented server is your hosting provider, usually through its control panel. Your domain’s DNS host cannot set it. For a mail server, the PTR should name the host the server introduces itself as, and that name must resolve back to the same IP.
dig -x 1.1.1.1 +shortone.one.one.one.What a PTR record is
DNS can only look up names, so an address is written as one. For IPv4 the four parts are reversed and in-addr.arpa is appended; for IPv6 every hexadecimal digit (nibble) of the full address is reversed and ip6.arpa is appended. The PTR record at that name holds the host name:
| Address | Reverse name (where the PTR lives) | PTR value |
|---|---|---|
| 1.1.1.1 | 1.1.1.1.in-addr.arpa | one.one.one.one. |
| 203.0.113.25 | 25.113.0.203.in-addr.arpa | mail.example.com. |
| 2001:db8::25 | 5.2.0.0…8.b.d.0.1.0.0.2.ip6.arpa | mail.example.com. |
The IPv6 name is shortened in the table. In full, with all 32 nibbles, the reverse name of 2001:db8::25 is:
5.2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpaReversing the order puts the network part on the right, where DNS delegation happens: whoever controls 113.0.203.in-addr.arpa controls the names of all 256 addresses in 203.0.113.0/24. That is the whole reason a PTR record is not yours to set in your domain’s zone.
How to do a reverse DNS lookup
Three tools, same answer. dig -x builds the reverse name for you and shows the whole response:
dig -x 1.1.1.1;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 45673
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; QUESTION SECTION:
;1.1.1.1.in-addr.arpa. IN PTR
;; ANSWER SECTION:
1.1.1.1.in-addr.arpa. 1647 IN PTR one.one.one.one.
;; SERVER: 1.1.1.1#53(1.1.1.1) (UDP)host 1.1.1.1
nslookup 1.1.1.11.1.1.1.in-addr.arpa domain name pointer one.one.one.one.
1.1.1.1.in-addr.arpa name = one.one.one.one.On Windows, nslookup 1.1.1.1 works the same way in cmd and PowerShell, and in PowerShell Resolve-DnsName -Name 1.1.1.1.in-addr.arpa -Type PTR asks for the record explicitly. IPv6 works with the same commands: dig -x 2606:4700:4700::1111 returns one.one.one.one. too.
When an address has no PTR record, the lookup ends in NXDOMAIN:
Host 154.23.20.104.in-addr.arpa. not found: 3(NXDOMAIN)
** server can't find 154.23.20.104.in-addr.arpa: NXDOMAINWithout a terminal, enter the address in the DNS lookup tool, which returns the PTR of an IP with its TTL, as our resolver in Amsterdam sees it.
Who controls the PTR record
The holder of the IP address block, never the DNS host of your domain. This is the most common confusion: people add a PTR record at Cloudflare or their registrar, see it saved, and wonder why dig -x ignores it. A reverse lookup never visits your domain’s zone. It follows the delegation of the address space, from the root to the regional internet registry to the network that holds the block. +trace shows the chain:
dig +trace -x 1.1.1.1in-addr.arpa. 172800 IN NS a.in-addr-servers.arpa.
1.in-addr.arpa. 86400 IN NS ns1.apnic.net.
1.1.1.in-addr.arpa. 86400 IN NS alec.ns.cloudflare.com.
1.1.1.1.in-addr.arpa. 1800 IN PTR one.one.one.one.APNIC, the registry for that part of the address space, delegates 1.1.1.in-addr.arpa to the name servers the holder of the block chose, here Cloudflare’s, and the PTR lives in that zone. For your own server, the last NS step names your provider’s name servers. A quicker way to see whose zone it is: ask for the SOA of the reverse name. The answer names the zone and its primary name server, and the same SOA comes back with every NXDOMAIN.
dig SOA 1.1.1.1.in-addr.arpa +noall +answer +authority1.1.1.in-addr.arpa. 1800 IN SOA alec.ns.cloudflare.com. dns.cloudflare.com. 2347919506 10000 2400 604800 1800| Your situation | Who sets the PTR | How |
|---|---|---|
| VPS or dedicated server at a host | The hosting provider | Control panel, API or a support ticket |
| Smaller block than a /24 at a provider | The provider, or you after RFC 2317 delegation | The provider CNAMEs each address into a zone you run |
| Your own address space (PI, an AS of your own) | You | Reverse zone delegated to your name servers at the registry |
| Home or office connection | The internet provider | Often fixed; some business lines allow a change on request |
To find out who holds a block, and so whom to ask, run whois on the address: the inetnum or NetRange lines give the block, netname or OrgName the holder, and there is usually an abuse contact.
Reverse DNS for a mail server
This is where a PTR record stops being cosmetic. A receiving server sees only the IP address that connected to it, and checks three things:
- the address has a PTR record;
- the name in it resolves (A for IPv4, AAAA for IPv6) back to the same address, which is called forward-confirmed reverse DNS;
- the name the server gave in its
EHLOgreeting matches, or at least is a real host name.
Gmail requires the first two from every sender, and answers 550 5.7.25 or a temporary 451 4.7.23 when they fail. Self-hosted receivers can do the same: Postfix’s reject_unknown_client_hostname refuses exactly those failures, with a temporary 450 by default. The SMTP standard says a receiver must not refuse mail only because the EHLO name does not match the address, but spam filters still score the mismatch, so make all three agree:
| Where | Value | Set by |
|---|---|---|
| PTR of 203.0.113.25 | mail.example.com | Your hosting provider's panel |
| A record of mail.example.com | 203.0.113.25 | Your domain's DNS host |
| EHLO / HELO name | mail.example.com | myhostname in Postfix |
| MX of example.com | 10 mail.example.com. | Your domain's DNS host |
Use a name in a domain you control, not the generic name a provider generates, which often contains the IP digits and looks like a home connection to spam filters. Point the PTR at a host name with an A record, not at a CNAME; RFC 1912 says as much. This script checks the round trip; replace YOUR_SERVER_IP with the sending address, an IPv6 one in its short lower-case form as dig prints it:
ip=YOUR_SERVER_IP
name=$(dig +short -x "$ip" | grep -v -e '^;' -e '\.arpa\.$' | head -n 1)
if [ -z "$name" ]; then
echo "no PTR record for $ip"
elif dig +short "$name" A "$name" AAAA | grep -qxF "$ip"; then
echo "OK: $ip -> $name -> $ip"
else
echo "MISMATCH: $name does not resolve back to $ip"
fiThe grep drops two kinds of lines dig +short can print before the name: a ;; warning after a retried query, and the alias that an RFC 2317 delegation puts in front of the PTR.
OK: 1.1.1.1 -> one.one.one.one. -> 1.1.1.1
OK: 2606:4700:4700::1111 -> one.one.one.one. -> 2606:4700:4700::1111
OK: 8.8.8.8 -> dns.google. -> 8.8.8.8
no PTR record for 104.20.23.154The mail server check runs the same test for the MX hosts of a domain, next to SPF, DKIM and DMARC, and the blacklist check tells you whether the address is on a public blocklist, which a correct PTR does not fix. Which ports the mail server itself needs is in the guide to SMTP ports.
How to set a PTR record at VMHeaven
On VMHeaven you set reverse DNS yourself in the panel, for VPS and dedicated servers. Do it in this order, because the PTR is only useful once its name resolves:
- 1Create the A record first
At your domain’s DNS host, point
mail.example.comat the server’s IPv4 address (and add an AAAA record if you will use IPv6), then check it. The name has to be a fully qualified host name, a FQDN such asmail.example.com.Linux · macOS dig +short mail.example.com A - 2Set the PTR for the IPv4 address
Open the server in the panel and go to the IPs tab. Each address shows its current rDNS value next to an Edit button. Enter the host name as PTR hostname and save.
- 3Set IPv6 PTRs, if the server has a prefix
Where the location’s pool has IPv6, a VPS gets a whole prefix rather than one address, shown as
delegated /64in the IPs tab. Manage opens its reverse DNS: add the address you actually use, which must sit inside the prefix, and its host name. - 4Wait, then verify
Changes propagate within about 30 minutes. Then run
dig -xand the check script above. If the name does not resolve back to the IP, mail providers ignore the PTR. - 5Make the server use the same name
Debian · Ubuntu (Postfix) sudo postconf -e myhostname=mail.example.com sudo systemctl reload postfixWhen Postfix delivers mail it greets with
myhostname, unlesssmtp_helo_namesays otherwise;postconf myhostname smtp_helo_nameshows both. Other mail servers have an equivalent setting.
Does a server that sends no mail need a PTR?
It is not required, but it helps. A PTR makes your address readable in other people’s logs and in traceroutes, and on a scanning box from the Pentesting KVM line, a PTR pointing at a host name whose web page explains the project and gives a contact address cuts the number of abuse reports. Reverse DNS also shows up on the receiving end: OpenSSH’s UseDNS option makes sshd look up and forward-confirm the name of every client. It is off by default in current OpenSSH, so a client without a PTR logs in normally; on a server where someone has turned it on, a reverse lookup that times out delays every login.
IPv6 reverse DNS
An IPv6 PTR works the same way, but the reverse name has 32 nibbles, one per hexadecimal digit of the full address, so 2001:db8::25 first becomes 2001:0db8:0000:0000:0000:0000:0000:0025. Let a tool write it rather than counting zeros: dig -x accepts the short form, and in Python ipaddress.ip_address("2001:db8::25").reverse_pointer prints the name.
A /64 holds far too many addresses to give each a record, so you set PTRs only for the addresses that send mail or need a name. Watch for a trap here: when a server has IPv6, Postfix with inet_protocols = all also delivers over IPv6, and Gmail rejects mail from an IPv6 address without a valid PTR with 550 5.7.1, citing its IPv6 sending guidelines. Either give the IPv6 address a PTR and an AAAA record too, or limit Postfix to IPv4 with inet_protocols = ipv4, which needs a full stop and start of Postfix, not a reload.
PTR record not updating or not accepted
- The old value still shows. Resolvers cache the PTR for its TTL, the number after the name in
dig -x. If there was no PTR before, they cache the NXDOMAIN instead, for the smaller of the SOA record’s own TTL and its last field (in the example below, 3600 seconds).dig +trace -xskips the resolver caches and shows what the provider’s name server answers right now. - Your own machine is stale. Flush its cache with
resolvectl flush-cacheson a Linux system running systemd-resolved, oripconfig /flushdnson Windows. - The PTR is right but mail is still rejected. Run the check script: the A record is missing, points elsewhere, or the PTR names a CNAME.
- Several PTR records for one IP. DNS allows it, but a receiver uses one of them, not necessarily the one matching your EHLO name. Keep one PTR per address; many addresses may point at the same host name.
- A PTR set at your domain’s DNS host. It is never queried; delete it and set the PTR at the provider that holds the IP.
- A zone file you run yourself shows strange names. In BIND syntax a PTR target without a trailing dot gets the zone name appended:
mail.example.comturns intomail.example.com.113.0.203.in-addr.arpa.. Writemail.example.com..
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 18648
20.104.in-addr.arpa. 3600 IN SOA cruz.ns.cloudflare.com. dns.cloudflare.com. 2288625501 10000 2400 604800 3600Every VMHeaven server, from a Standard KVM VPS to a dedicated server, comes with its own IPv4 address whose reverse DNS you control from the panel. For the forward side of the same records, see What is DNS.
Frequently asked
Who sets the PTR record for my IP address?
The holder of the IP address block, which for a rented server is the hosting provider, usually through its control panel. A PTR record added at your domain's DNS host is never queried, because reverse lookups follow the delegation of the address space, not your domain.
What should the PTR record of a mail server be?
The fully qualified host name the server uses in its EHLO greeting, such as mail.example.com, and that name needs an A record (AAAA for IPv6) pointing back to the same IP. Gmail rejects or defers mail from addresses that fail this forward-confirmed check.
Why does my new PTR record not show up yet?
Resolvers that looked up the address before keep the old answer, or the earlier NXDOMAIN, until its TTL runs out. 'dig +trace -x YOUR_IP' asks the provider's name servers directly and shows the current value; at VMHeaven a change made in the panel propagates within about 30 minutes.