NSEC records let a signed zone prove a negative: that a name does not exist, or that it exists but has no record of the requested type.
cloudflare.com. 300 IN NSEC \000.cloudflare.com. A NS SOA PTR HINFO MX TXT AAAA LOC SRV NAPTR CERT SSHFP RRSIG NSEC DNSKEY TLSA SMIMEA HIP CDS CDNSKEY OPENPGPKEY SVCB HTTPS URI CAA
; next name \000.cloudflare.com.; types present: A, NS, SOA, PTR, HINFO, MX, TXT, AAAA, LOC, SRV, NAPTR, CERT, SSHFP, RRSIG, NSEC, DNSKEY, TLSA, SMIMEA, HIP, CDS, CDNSKEY, OPENPGPKEY, SVCB, HTTPS, URI, CAA
isc.org. 3600 IN NSEC _acme-challenge.isc.org. A NS SOA MX TXT AAAA NAPTR RRSIG NSEC DNSKEY CDS CDNSKEY HTTPS CAA TYPE65534
; next name _acme-challenge.isc.org.; types present: A, NS, SOA, MX, TXT, AAAA, NAPTR, RRSIG, NSEC, DNSKEY, CDS, CDNSKEY, HTTPS, CAA, TYPE65534
nlnetlabs.nl. 240 IN NSEC 6only.nlnetlabs.nl. A NS SOA MX TXT AAAA NAPTR RRSIG NSEC DNSKEY
; next name 6only.nlnetlabs.nl.; types present: A, NS, SOA, MX, TXT, AAAA, NAPTR, RRSIG, NSEC, DNSKEY
ietf.org. 1800 IN NSEC \000.ietf.org. A NS SOA PTR HINFO MX TXT AAAA LOC SRV NAPTR CERT SSHFP RRSIG NSEC DNSKEY TLSA SMIMEA HIP CDS CDNSKEY OPENPGPKEY SVCB HTTPS URI CAA
; next name \000.ietf.org.; types present: A, NS, SOA, PTR, HINFO, MX, TXT, AAAA, LOC, SRV, NAPTR, CERT, SSHFP, RRSIG, NSEC, DNSKEY, TLSA, SMIMEA, HIP, CDS, CDNSKEY, OPENPGPKEY, SVCB, HTTPS, URI, CAA
In the classic design, the zone's names are sorted in canonical order and each name gets an NSEC record pointing to the next one, plus a bitmap of the types present at that name. To prove b.example.com does not exist, the server returns the signed NSEC for a.example.com whose "next" is c.example.com. The side effect is zone walking: anyone can follow the chain and list every name in the zone. NSEC3 (RFC 5155) hashes the names to make that harder.
Online signers such as Cloudflare use "compact" or "black lies" denial instead. They synthesise an NSEC whose next name is the queried name with a \000. label added, so nothing about the rest of the zone leaks. For a non-existent name they mark it with the NXNAME pseudo-type. The cloudflare.com and ietf.org examples below show this pattern.
a.example.com. 3600 IN NSEC c.example.com. A MX RRSIG NSEC
; next-owner-name type-bitmap
Wire format: RDATA is the next owner name (uncompressed) and a type bitmap in windowed form.
| Field | Meaning |
|---|---|
| Next owner name | The next name in canonical order. The last NSEC in the zone points back to the apex. |
| Type bitmap | Every type that exists at the owner name, including RRSIG and NSEC themselves. |