is it DNS? wiki/Reference/Reverse DNS: in-addr.arpa and ip6.arpa
Reference

Reverse DNS: in-addr.arpa and ip6.arpa

Reverse DNS is the IP-to-name lookup. It's the part of DNS that looks weird the first time you see it, because the zones have names like 53.100.51.198.in-addr.arpa instead of example.com. The structure is fine. It's the ergonomics of ip6.arpa that hurt.

Why reverse DNS exists#

Forward DNS asks: "What's the address of example.isitdns.net?": a name in, an address out.

Reverse DNS asks the other direction: "Who lives at 198.51.100.53?": an address in, a name out. Used by:

  • mail servers verifying that the connecting IP has matching forward/reverse records (the "FCrDNS check": see ptr for how FCrDNS asymmetry breaks mail delivery)
  • SSH log enrichment (sshd reverse-resolves the connecting client when UseDNS is enabled; note it defaults to no in modern OpenSSH, precisely because a slow PTR lookup delays logins)
  • spam scoring (mail from a host with no PTR is suspicious)
  • observability tooling labeling traffic by host name instead of IP
  • humans reading tcpdump output without going cross-eyed

The DNS protocol has exactly one way to do this: define a special domain tree where every IP address is encoded as a name, and resolve it the normal way.

The in-addr.arpa tree (IPv4)#

The IPv4 address 198.51.100.53 becomes the DNS name:

53.100.51.198.in-addr.arpa
 |   |   |   |  +--------- the reverse-DNS root for IPv4
 |   |   |   +------------ most-significant octet
 |   |   +---------------- next octet
 |   +-------------------- next octet
 +------------------------ least-significant octet (the host)

Reversing the octets lets the DNS hierarchy walk the same way it does for forward names: most-general on the right, most-specific on the left. The root delegates arpa, which delegates in-addr.arpa, which delegates 198.in-addr.arpa, and so on. For RFC 1918 private space (10/8, 172.16/12, 192.168/16) the public tree dead-ends on purpose: IANA delegates those reverse zones to the AS112 blackhole servers, which serve them as empty zones: SOA and NS at the zone name itself, NXDOMAIN for every address inside it. RFC 6303 tells recursive resolvers to serve the same empty zones out of their own data, so that NXDOMAIN for a name inside the block arrives without anyone being asked. So on a private network you stand up your own reverse zone. You can watch a resolver do this below.

The shorthand form, letting dig handle the name reversal:

dig @1.1.1.1 -x 198.51.100.53

What it actually sends on the wire:

dig @1.1.1.1 53.100.51.198.in-addr.arpa PTR

198.51.100.x is one of the three RFC 5737 documentation prefixes (TEST-NET-2). Nobody publishes PTRs in it, and RFC 6303 section 4.2 lists 100.51.198.in-addr.arpa as a locally served zone, so a resolver returns NXDOMAIN for these names out of its own empty zone instead of walking the tree. They are shown here only to illustrate the name format. For a live working example, see the Quick check section below.

The shorthand form for nslookup:

nslookup 198.51.100.53 1.1.1.1

What it actually sends on the wire:

nslookup -type=PTR 53.100.51.198.in-addr.arpa 1.1.1.1

Both forms send a PTR query and return a PTR record. Every reverse zone also requires an SOA at the apex and NS records, just like any other zone. For classless sub-range delegations (RFC 2317), the parent /24 zone also uses CNAME records to redirect individual host queries to the delegated sub-zone.

The ip6.arpa tree (IPv6)#

Same idea, with twice as much pain. Each IPv6 address is 128 bits = 32 hex nibbles, and reverse DNS encodes one nibble per label, in reverse order. The address 2001:db8::1 becomes:

1.0.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.arpa

Yes really. Thirty-two single-character labels. Plus ip6.arpa. That's the lookup name for 2001:db8::1.

Ouch, my eyes. This is why every reverse-DNS tool on the planet has a built-in formatter. You will never type these by hand. dig -x does it for you.

The shorthand form (using the RFC 3849 documentation prefix to illustrate the format):

dig @1.1.1.1 -x 2001:db8::1

What hits the wire:

dig @1.1.1.1 1.0.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.arpa PTR

2001:db8:: is the RFC 3849 documentation prefix. It has no reverse zone, so both commands return NXDOMAIN. These are shown to illustrate the nibble format, not as live lookups. For a working IPv6 PTR example, see the ptr page.

The shorthand form for nslookup:

nslookup 2001:db8::1 1.1.1.1

What hits the wire:

nslookup -type=PTR 1.0.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.arpa 1.1.1.1

The two principles to remember:

  1. One nibble per label. Not one hex-byte (two nibbles) per label. One nibble.
  2. Reversed nibble order. Most-significant nibble of the original address ends up on the right.

That's it. The verbosity is the price of using the same delegation machinery as forward DNS.

Delegation: who's authoritative for what#

For IPv4:

RangeAuthoritative for the reverse zone
Public, allocated to your ISPUsually the ISP: call them if you want a custom PTR for your static IP
Public, allocated to you (BYOIP)You: your RIR (or the ISP/LIR you got the block through) delegated the relevant /24 (or smaller, via RFC 2317 classless delegation)
RFC1918 (10/8, 172.16/12, 192.168/16)You. The public zones (168.192.in-addr.arpa etc.) are delegated to the AS112 blackhole servers (blackhole-1.iana.org, blackhole-2.iana.org), which answer NOERROR with their own NS at the zone name and NXDOMAIN for every address inside it, and most resolvers short-circuit them locally per RFC 6303. Stand up your own.
Link-local (169.254/16)No one usable: 254.169.in-addr.arpa points at the same blackhole servers, so these addresses never get real global reverse DNS

For IPv6 the analogous split applies. ULA space (fc00::/7) is yours to host; public allocations are usually delegated by your RIR.

The categorization of public, private, and documentation addresses is summarized at the addresses you'll meet.

Watch a resolver answer private space itself#

Ask a public resolver who serves the reverse zone for 192.168.0.0/16:

curl -s -H 'accept: application/dns-json' \
  'https://cloudflare-dns.com/dns-query?name=168.192.in-addr.arpa&type=NS'
{"Status":3,"TC":false,"RD":true,"RA":true,"AD":false,"CD":false,"Question":[{"name":"168.192.in-addr.arpa","type":2}]}

Status 3 is NXDOMAIN, with no Answer and no Authority section, and 8.8.8.8 returns the same. That answer comes from the resolver itself, not from recursion: ask an AS112 server this exact question directly and it answers NOERROR with the two blackhole-*.iana.org NS records, aa set (measured 2026-09-04 against blackhole-1.iana.org from a network with no port-53 interception). A resolver that had really walked the tree would have returned those.

Keep two things apart here, because they do not say the same thing. RFC 6303 section 3 asks a resolver for name errors on queries within the locally served zones, "with the obvious exception of queries for the zone name itself where SOA, NS, and 'no data' responses will be returned as appropriate to the query type". BIND implements that literally: its built-in empty zones are "for SOA and NS records only" (BIND 9 ARM), so 168.192.in-addr.arpa NS gets NOERROR and an NS record from a stock BIND, and only a name below the apex gets NXDOMAIN. 1.1.1.1 and 8.8.8.8 are stricter than the RFC and return NXDOMAIN at the zone name too. Ask for a name inside the block and everyone agrees:

curl -s -H 'accept: application/dns-json' \
  'https://cloudflare-dns.com/dns-query?name=1.1.168.192.in-addr.arpa&type=PTR'
{"Status":3,"TC":false,"RD":true,"RA":true,"AD":false,"CD":false,"Question":[{"name":"1.1.168.192.in-addr.arpa","type":12}]}

Unbound ships the same zones as built-in local-zone defaults.

RFC 2317: classless reverse delegation#

If your ISP delegates a /26 to you, the classful reverse zone (x.y.z.in-addr.arpa: a /24) doesn't line up. RFC 2317 defines a CNAME-based trick to delegate a sub-range. You don't need this for RFC 1918 space; you do need it if you're getting a small public allocation. The pattern shows up in customer environments more than home labs.

PTR records inside any reverse zone are documented on the PTR page, including the FCrDNS gotchas that trip up mail delivery.

Quick check that reverse is working#

Pick an IP you know has a PTR record. Cloudflare's 1.1.1.2 works reliably, and unlike 1.1.1.1 its reversal is visible (1.1.1.2 becomes 2.1.1.1.in-addr.arpa):

dig @1.1.1.1 -x 1.1.1.2 +short
security.cloudflare-dns.com.

With nslookup:

nslookup 1.1.1.2 1.1.1.1
2.1.1.1.in-addr.arpa	name = security.cloudflare-dns.com.

Authoritative answers can be found from:

Exact framing varies by nslookup build: current BIND 9.18 nslookup prints just the answer for the by-IP form, while other builds add a Server: banner and a Non-authoritative answer: line first, as in the next example. The answer line is the part that matters.

Or query the reverse name directly:

dig @1.1.1.1 2.1.1.1.in-addr.arpa PTR +short
security.cloudflare-dns.com.
nslookup -type=PTR 2.1.1.1.in-addr.arpa 1.1.1.1
Server:		1.1.1.1
Address:	1.1.1.1#53

Non-authoritative answer:
2.1.1.1.in-addr.arpa	name = security.cloudflare-dns.com.

Authoritative answers can be found from:

Failure modes to distinguish:

  • NXDOMAIN: the reverse zone exists and is authoritative, but no PTR is provisioned for that IP. (Also what you get for RFC 1918 and documentation addresses, per the delegation table above.)
  • SERVFAIL: the reverse zone delegation is broken (missing or misconfigured NS/glue), DNSSEC validation failed, or the resolver gave up trying to reach the authoritative servers.
  • Timeout: your query never got any answer at all, which points at the path between you and the resolver, not the authoritative side. Start at the L3 path to the resolver.

See also#