🪵 Stub zones
A stub zone says: "I keep a tiny copy of another zone's NS and SOA records so I can query its authoritative servers directly, skipping the full hierarchy walk: but I don't serve any of the zone's data, and I don't transfer all of it." Stubs are a caching shortcut, not a delegation and not a forward.
What it is#
A stub zone holds only:
That's it. When a resolver gets a query for a name inside a stub zone, it doesn't try to answer from the stub: instead it knows the authoritative servers (from the stub's NS list) and goes to them directly, skipping the full . → TLD → zone hierarchy walk. See query-types for how this fits into the broader recursion model.
Stub zones poll the master servers on the zone's SOA refresh timer to keep the NS list current, the same schedule a secondary uses. NOTIFY generally does not update a stub: BIND's allow-notify applies only to secondary and mirror zones, and Microsoft DNS refreshes stubs on the SOA interval. NS + SOA (plus glue) is the only data they ever transfer.
Stub zones are not defined in any RFC. They are an implementation feature: "Stub zones are not a standard part of the DNS; they are a feature specific to the BIND implementation" (BIND 9 ARM, Zone Types). Microsoft DNS implements the same idea (Understanding Zone Types).
When to use it#
- Cross-team / cross-org referrals where you want fast resolution into a peer's zone without operating as a secondary.
- Speeding up lookups into a frequently-queried external zone. Skip the recursion walk, hit the authoritative directly.
- Tracking NS changes automatically. If the target zone changes its NS list, a stub picks that up via SOA refresh: a forward zone with hard-coded forwarder IPs doesn't.
When not to use it#
- When you want to act as a secondary copy of the whole zone: use a real secondary (which transfers all records).
- When you don't want clients to talk to the authoritative servers at all: use forward instead. (A stub uses the upstream NS; a forward talks through your resolver to the upstream.)
- When you own the records: use auth.
Stub vs forward vs delegation: the cheat-sheet diagram#
AUTH I have the data.
answer -> client (aa=1)
STUB I know who has the NS. My resolver queries them directly,
bypassing the full root walk. Client still talks to me. (aa=0)
FORWARD I have a configured upstream resolver. Send it there.
forward -> configured upstream -> answer -> client (aa=0)
DELEGATION I publish NS pointing downstream. Clients walking the hierarchy
see those NS and go there directly.
(NO involvement from my server beyond returning the NS referral)Real-world examples#
| Use case | Stub zone name | Master |
|---|---|---|
| Resolver should know NS for a frequently-queried partner zone | partner.example.com | partner's authoritative NS IPs |
| Internal sub-team running its own authoritative server but queryable from the main resolver | subnet-b.internal.example | sub-team's primary nameserver |
| Force reverse lookups for private (RFC 1918) space to internal servers | 10.in-addr.arpa. | internal authoritative NS for 10/8 |
How to configure a stub zone#
The shape is the same across DNS servers: a zone object with a "stub" type and a list of master nameservers to pull NS + SOA from. In BIND that is type stub; plus a primaries list; in Microsoft DNS it is a stub zone in DNS Manager or dnscmd <server> /ZoneAdd <zone> /Stub <masterIP> (Add a Stub Zone). Two common variants skip the transfer entirely and take the server list as static configuration instead: BIND's type static-stub (BIND 9 ARM, Zone Types) and Unbound's stub-zone (unbound.conf(5)). Not every server implements stubs explicitly; some deployments use forward zones or true secondaries instead. Check your DNS server's documentation for the exact syntax. See nslookup-and-dig for the client-side tools you will use to verify a stub zone is working.
How to tell a stub is working#
Send a query to your local resolver for a name inside the stubbed zone. Replace <resolver> with your resolver's IP and www.partner.example.com with a name in the zone you stubbed.
dig @<resolver> www.partner.example.com Anslookup -type=A www.partner.example.com <resolver>
nslookupnever prints the DNS header flags line; its one hint is theNon-authoritative answer:label, printed whenever the answer hasaa=0. Usedigfor flag inspection. See nslookup-and-dig for a full comparison.
A stub doesn't change the answer: only the path to get it. Your resolver still answers the client, so aa=0 in the response the client sees. Only a query sent directly to the authoritative server would return aa=1: the aa bit marks a server that is an authority for the queried name (RFC 1035 §4.1.1). Compare latency against the equivalent query run before the stub was configured: the NS walk is skipped, so the first lookup should be noticeably faster.
Gotchas#
- Stubs are NOT a copy of the data. They cache NS + SOA. If the authoritative NS list goes stale, your resolver keeps querying dead servers until the next SOA refresh picks up the new list.
- SOA refresh interval matters. A stub respects the SOA's
refreshfield on the master zone: short refresh means more responsive, more load on the master. BIND clamps the interval betweenmin-refresh-time(default 300 seconds) andmax-refresh-time(default 4 weeks) for secondary and stub zones (BIND 9 ARM). - Stub vs secondary confusion. A secondary copies the whole zone (AXFR/IXFR: see transfer). A stub only copies NS+SOA. They are different zone types in every server that supports both.
- Stubs lose to global forwarding. You cannot define both a stub zone and a forward zone for the same name (one zone object per name per view), but a global
forwarderslist still covers names inside a stub zone, so queries go to the forwarder instead of the stubbed NS. In BIND, exempt the zone with an emptyforwarders {};in the stub zone block; per-zone forwarder settings override the global ones (BIND 9 ARM, forwarders). - You cannot stub a zone you are authoritative for (in the same view). Servers reject the configuration: Microsoft DNS refuses to host a stub zone on a server that is authoritative for the same zone (Add a Stub Zone), and BIND will not load two zones with the same name in one view.