is it dns? / wiki ← back to the live monitor

Delegated zones

A delegated zone says: "I'm publishing NS records that point at a different nameserver for this sub-name. Clients should go ask them directly." Delegation is how the DNS hierarchy is built: it's what .com does when it tells you "go ask example.com's nameservers."

What it is#

In the parent zone you publish:

  • An NS record set at the child name, listing the nameservers that own the child zone
  • Glue records (A/AAAA) for any NS name that lives inside the delegated zone; required in that case, or resolvers cannot follow the referral (in-bailiwick: see "Glue" below)
  • If the child zone is DNSSEC-signed, a DS record at the same name, fingerprinting the child's key so the chain of trust crosses the cut (see dnssec)

That's it. The parent no longer answers for names under the child. A resolver walking the hierarchy hits the parent, gets back a referral ("go talk to those NS"), and continues there.

The child runs its own authoritative server. From the parent's perspective the child is opaque: it could be anything, anywhere.

When to use it#

  • Sub-team or sub-product owns the namespace. customers.example.com is owned by a team that runs their own auth servers.
  • Lab / pre-prod separation. Delegate lab.example.com to lab nameservers so prod is not on the hook for lab churn.
  • Sub-delegations in reverse zones. RFC 2317 classless reverse delegations are a special case of this: see Reverse DNS: in-addr.arpa and ip6.arpa.
  • Geo or capability splits: eu.example.com to a regional cluster.
  • Customer-owned subdomains. Customer points their NS records for <them>.yourservice.com at their own DNS; you delegate.

When not to use it#

  • If you just want your resolver to chase the queries to someone else's DNS without changing what the world sees: use forward instead.
  • If you own the records anyway: keep them in auth.

Real-world examples#

Parent zoneChild nameWhere it goes
example.comcustomers.example.comCustomers' SaaS namespace, owned by a SaaS team
example.comeu.example.comEU geo cluster's authoritative DNS
example.comcorp.example.comActive Directory-owned namespace
51.198.in-addr.arpa100.51.198.in-addr.arpaA /24 [[reverse-dns
isitdns.netprobe.isitdns.netThis wiki's worked example of delegating a subdomain to its own authoritative nameservers

The probe.isitdns.net row is the worked example used below. Its nameservers are being rebuilt and the delegation is offline right now; the .net to isitdns.net delegation one level up is live, and the walkthrough below starts there.

How to create a delegation#

The setup is the same across every DNS server:

  1. In the parent zone, add an NS record set at the child's apex naming the child's nameservers.
  2. If the child's nameservers live inside the delegated zone (in-bailiwick), also add A/AAAA glue records alongside the NS.
  3. On the child's authoritative server, create the child zone and confirm its apex NS records list the same nameservers.
  4. If the child zone is DNSSEC-signed, also publish its DS record in the parent at the child's name; without it, validating resolvers treat the child as unsigned (see dnssec).

In zone-file form the parent-side configuration looks like:

customers.example.com.       86400  IN  NS  ns1.customers.example.com.
customers.example.com.       86400  IN  NS  ns2.customers.example.com.
ns1.customers.example.com.   86400  IN  A   203.0.113.20
ns2.customers.example.com.   86400  IN  A   203.0.113.21

The last two lines are glue: A records for NS names that live inside the delegated zone itself.

Most managed DNS providers expose a form or API call that produces the same records. The zone-file form is shown here because it's server-agnostic and readable.

Glue records: the in-bailiwick case#

If your NS name lives inside the delegated zone, for example ns1.customers.example.com, a resolver chasing customers.example.com NS gets ns1.customers.example.com. back and immediately needs that NS's address to make the next call. But the address record lives inside the delegated zone, which the resolver has not visited yet. That is a chicken-and-egg problem.

The parent solves this by publishing glue records: A/AAAA records for the NS name, served in the Additional section alongside the NS referral. The resolver does not need to go anywhere else to get the address.

The probe.isitdns.net delegation above is the worked example of this: pns1.isitdns.net and pns2.isitdns.net are both in-bailiwick (both live inside isitdns.net), so the parent publishes their A records as glue.

If your NS names live in a different zone (for example, ns1.example-dns-provider.com for example.com), glue is not needed: the resolver can look those up via the normal path. Out-of-bailiwick NS means no glue, which means less to break.

Querying a live delegation#

The parent side of a delegation answers with a referral, not a normal answer: the NS records come back in the AUTHORITY section, the ANSWER section is empty, and the aa flag stays clear, because delegation NS records are not authoritative data in the parent (RFC 1034 section 4.3.2). You can watch a live one at the .net to isitdns.net cut:

dig @a.gtld-servers.net isitdns.net NS +norec
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 2, ADDITIONAL: 1

;; AUTHORITY SECTION:
isitdns.net.  172800  IN  NS  hera.ns.cloudflare.com.
isitdns.net.  172800  IN  NS  coleman.ns.cloudflare.com.

No glue rides along here (the single additional record is the EDNS OPT pseudo-record): coleman and hera live under cloudflare.com, outside the zone being cut, so a resolver looks their addresses up separately.

The worked example: a delegation with in-bailiwick glue. probe.isitdns.net is this wiki's delegated sub-zone of isitdns.net. You can watch the full picture with three queries.

🚧 Demo server note. The probe platform and its nameservers pns1/pns2 are being rebuilt, so the delegation records are removed from isitdns.net for now and the three queries below will not answer today (these names return NOERROR with an empty answer, not NXDOMAIN: isitdns.net is DNSSEC-signed on Cloudflare, which denies nonexistent names with compact denial of existence, a synthetic NSEC carrying the NXNAME bit, rather than a plain NXDOMAIN, per RFC 9824). The exchanges are kept as the teaching example; the mechanics are unchanged and reproduce against any delegation with in-bailiwick nameservers.

Step 1: ask the parent's authoritative server for the delegation.

The parent for isitdns.net is Cloudflare. Query it directly:

dig @coleman.ns.cloudflare.com probe.isitdns.net NS
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 2, ADDITIONAL: 3

;; AUTHORITY SECTION:
probe.isitdns.net.  300  IN  NS  pns1.isitdns.net.
probe.isitdns.net.  300  IN  NS  pns2.isitdns.net.

;; ADDITIONAL SECTION:
pns1.isitdns.net.   300  IN  A   142.93.10.167
pns2.isitdns.net.   300  IN  A   158.101.0.110

A referral, same shape as at the .net cut: NS in the AUTHORITY section, aa clear. This time glue A records ride along in the ADDITIONAL section, because pns1 and pns2 live inside isitdns.net, which the parent controls.

nslookup -type=NS probe.isitdns.net coleman.ns.cloudflare.com

Step 2: fetch the glue records from the same parent.

dig @coleman.ns.cloudflare.com pns1.isitdns.net A
dig @coleman.ns.cloudflare.com pns2.isitdns.net A
pns1.isitdns.net.  300  IN  A  142.93.10.167
pns2.isitdns.net.  300  IN  A  158.101.0.110

These come back as ordinary authoritative answers (aa set, records in the ANSWER section) because pns1 and pns2 sit in isitdns.net itself, beside the cut rather than under it. The parent publishes the same addresses alongside the NS referral so a resolver can reach the child without an extra lookup chain.

Step 3: verify the child answers for its own zone.

dig @pns1.isitdns.net probe.isitdns.net SOA +norec
;; ANSWER SECTION:
probe.isitdns.net.  300  IN  SOA  pns1.isitdns.net. hostmaster.isitdns.net. (
                                    2026061511 7200 3600 1209600 300 )

The serial (2026061511 above) increments each time the zone is updated, so your output will show a different value. The other fields (MNAME, RNAME, and the refresh/retry/expire/minimum timers) should be stable.

nslookup -norecurse -type=SOA probe.isitdns.net pns1.isitdns.net

On a network that intercepts port 53 (captive portals, some home routers), a @server query is answered by the interceptor rather than the named server. If you see only rd ra flags without aa, that is your network, not pns1.

A NOERROR answer with a SOA record from the child proves the delegation is not lame. The aa (authoritative answer) flag in the header confirms pns1 is serving this zone itself, not forwarding to another server. If you got REFUSED instead, the child server does not know about the zone and every referral to it would dead-end.

Checking consistency: do the child apex NS records match the parent's delegation?

dig @pns1.isitdns.net probe.isitdns.net NS +norec
;; ANSWER SECTION:
probe.isitdns.net.  300  IN  NS  pns1.isitdns.net.
probe.isitdns.net.  300  IN  NS  pns2.isitdns.net.

Parent says pns1/pns2, child says pns1/pns2. They match. The child's apex NS set is the authoritative one: caches rank it above the parent's referral copy and replace the referral data with it once seen (RFC 2181 section 5.4.1). A mismatch means different resolvers converge on different NS sets (see Gotchas below).

What dig +trace shows#

dig +trace walks the full hierarchy from the root downward, exactly as a recursive resolver would. It prints each referral as it crosses a delegation boundary. The ;; Received line after each referral shows which server answered and how many bytes came back.

dig +trace isitdns.net

nslookup has no +trace equivalent. Use dig.

Gotchas#

  • Apex of the child must agree with the parent's delegation. If you delegate customers.example.com to ns1/ns2, the child zone's apex NS records must also list ns1/ns2. The child's authoritative set outranks the parent's copy in caches (RFC 2181 section 5.4.1), so with a mismatch, which NS set a resolver uses depends on what its cache has seen; diagnostic tools like DNSViz flag the inconsistency. The consistency check in the section above shows how to verify this yourself.
  • Lame delegation. An NS that does not actually serve the zone. Resolvers get a referral, contact the server, get REFUSED, fall back to the next NS: slow and brittle. Always verify each NS before relying on it:
  dig @ns1.customers.example.com customers.example.com SOA +norec

A NOERROR answer with a SOA record means the NS is authoritative. REFUSED or SERVFAIL means lame.

  • TTL on the delegation matters. A long TTL on NS records means you cannot change them quickly. 3600 (1 h) is a reasonable default; lower it before a planned move.
  • Delegation in a split-horizon view. Delegating in one view does not delegate in other views. If you need the delegation visible everywhere, add it in every applicable view.
  • Do not delegate to yourself. If the same server holds both the parent and a sub-zone, the delegation in the parent is redundant: the server answers from the child zone regardless. The risk is operational: two zone objects with overlapping scope create confusion. Keep the sub-zone and omit the delegation, or delegate to a genuinely separate server.

See also#

  • auth: what the child runs internally
  • forward · stub: the alternatives when you want resolver behavior without changing the public namespace
  • ns: the NS record itself
  • soa: the SOA record at the child zone apex, which anchors the child zone
  • dnssec: the DS record, which carries the chain of trust across the delegation
  • Reverse DNS: in-addr.arpa and ip6.arpa: the trickiest delegation case
  • anatomy-of-a-query: how a resolver walks delegations
  • split-horizon: delegation behavior when views are in play