During an incident, named can feel like a black box. A single process handles packet reception, DNS parsing, ACL evaluation, cache lookup, zone lookup, recursive fetch, DNSSEC validation, RPZ policy enforcement, and response serialization. There is no separate resolver process, no separate authoritative process, no separate cache daemon. Every query flows through the same pipeline, and every subsystem competes for the same pool of CPU, memory, file descriptors, and kernel network buffers.
What it is and why it matters
BIND (ISC BIND 9.x) serves as both a recursive resolver and an authoritative server, and can do both on the same instance. ISC explicitly recommends against mixed-role deployments.
The failure modes are not random. They follow from the architecture. When the cache subsystem and the zone database share the same process memory, the recursive fetch state table has a hard limit, and the network manager uses one worker thread per core, you can trace any symptom back to the component responsible.
The statistics channel exposes counters via JSON at /json/v1/* and XML at /xml/v3/*. Counter names are stable across BIND 9.16+. They are cumulative since process start, zero-valued counters are omitted by default, and there is no native end-to-end latency histogram. Knowing which counter maps to which pipeline stage is what separates effective monitoring from noise.
How it works
The query pipeline
Every DNS query that reaches named passes through a fixed sequence of stages:
flowchart LR
A[Receive packet] --> B[Parse]
B --> C{ACL / view}
C -->|deny| R[REFUSED]
C -->|allow| D{Recursive?}
D -->|yes| E{Cache hit?}
D -->|no| F[Zone DB]
E -->|hit| P[RPZ + DNSSEC]
E -->|miss| G[Fetch upstream
via recursive-clients slot]
G --> P
F --> P
P --> S[Serialize + send]The stages, with their operational significance:
Receive. UDP sockets handle the majority of traffic. TCP handles queries that exceed UDP size limits, zone transfers, and clients configured for TCP. The kernel’s UDP receive buffer sits between the wire and named. If that buffer overflows, packets are dropped before BIND sees them. There is no counter, no log entry, no signal in the statistics channel. The only evidence is RcvbufErrors in the Udp: line of /proc/net/snmp.
Parse. The incoming packet is decoded into an internal query structure. Malformed packets consume extra CPU here. OpCodes and QTypes are classified into the statistics counters at this stage.
ACL and view check. BIND evaluates match-clients, allow-query, allow-recursion, and view configuration. A denied query returns REFUSED. This is correct behavior, not an error. On public authoritative servers, background REFUSED from random Internet hosts probing for open recursion is expected noise.
Cache lookup (recursive path). If recursion is enabled for the matching view, BIND checks the in-memory cache. A hit returns the cached answer directly. A miss triggers a recursive fetch upstream.
Zone lookup (authoritative path). If the query targets a zone BIND is authoritative for, the answer comes from the in-memory zone database. This is a pure memory lookup, typically sub-millisecond.
Recursive fetch. On a cache miss, BIND sends a query upstream. Each in-flight recursive query holds a slot in the recursive-clients table. The default limit is 1000, with a soft quota at 90% (900). Beyond the soft quota, BIND starts rejecting new recursive queries. At the hard limit, new recursive queries receive SERVFAIL. Each slot is held for the duration of the upstream fetch, bounded by resolver-query-timeout (default 10 seconds). Slow or unresponsive upstream servers hold slots longer, which is the mechanism behind the most common recursive resolver outage pattern: upstream latency fills the table, and healthy queries get rejected as collateral damage.
Apply RPZ and DNSSEC. Response Policy Zone rules are evaluated, potentially rewriting the response. DNSSEC validation runs if enabled, adding cryptographic verification overhead. This is CPU-intensive, especially for RSA keys above 2048 bits.
Serialize and send. The response is encoded and written to the socket.
Internal machinery
Network manager (netmgr). Since BIND 9.18, the legacy socket manager is gone entirely. netmgr uses libuv for asynchronous I/O multiplexing with one worker thread per CPU core by default. The -n flag overrides the worker count. CPU saturation manifests as worker thread contention and softirq pressure, not as a clean queue depth metric.
Cache subsystem. For recursive resolvers, the in-memory cache is bounded by max-cache-size. The default is 90% of physical memory for views with recursion yes, and 2 MB for views with recursion no. Eviction under memory pressure discards entries by LRU, tracked via the DeleteLRU counter in cachestats. This reduces cache hit ratio, which increases outbound queries, which increases latency and resource consumption. The result is a self-reinforcing degradation loop. BIND does not release freed memory back to the OS efficiently due to allocator fragmentation. RSS climbs and stays.
Zone database. Authoritative zone data lives in memory. Journal files (.jnl) handle dynamic updates and IXFR. Zone transfers (AXFR for full, IXFR for incremental) use TCP on port 53. The SOA serial number drives the transfer protocol between primaries and secondaries.
Address Database (ADB). Tracks reachability and round-trip time to upstream authoritative servers for server selection during recursive resolution. BIND preferentially queries faster nameservers and applies an RTT band so that nameservers within a similar latency range are used interchangeably. The ADB can consume significant memory with many unique upstream targets.
DNSSEC engine. In recursive mode, validates every answer against the chain of trust using managed trust anchors via RFC 5011. In authoritative mode, signs zones with inline signing. DNSSEC validation requires accurate time. Clock drift outside RRSIG validity windows causes validation failures (SERVFAIL) for signed domains while unsigned domains continue to work.
Control plane. rndc commands flow via TCP port 953 (or a Unix socket). The statistics channel serves HTTP. These are separate from the data plane on port 53 and can degrade independently. If rndc status hangs while queries still work, the control plane is starved, which blocks incident response before the query path fails completely.
Where it shows up in production
The pipeline and machinery produce predictable failure archetypes when resources are constrained. These are not edge cases. They are the direct consequences of the architecture under load.
| Failure pattern | Pipeline stage | What happens |
|---|---|---|
| Recursive client exhaustion | Recursive fetch | Outstanding fetches pile up, fill the table, new queries get SERVFAIL |
| Cache pressure spiral | Cache lookup | Undersized cache drives low hit ratio, more upstream queries, more latency |
| Upstream dependency failure | Recursive fetch | Forwarders slow or unreachable, slots consumed for full timeout duration |
| UDP packet drops | Receive | Kernel buffer overflows, packets lost before BIND sees them |
| Zone staleness cascade | Zone lookup | Transfer failures leave secondaries serving stale data until SOA expire |
| DNSSEC time bomb | Apply RPZ/DNSSEC | Expired signatures cause validating resolvers worldwide to reject the zone |
| Memory exhaustion to OOM | All stages | Unbounded cache or leak triggers OOM kill, cold restart storm follows |
Each pattern traces to a specific stage and a specific contested resource. The recursive client exhaustion archetype is the direct consequence of the recursive fetch stage holding slots with a hard cap. The cache pressure spiral is the direct consequence of LRU eviction interacting with recursive fetch slot demand.
Why mixed-role servers mask failure signals
ISC explicitly recommends against combining authoritative and recursive functions on the same server set. The recursive workload is variable and unpredictable, and consumes resources needed for authoritative service.
The monitoring problem is structural. When a single BIND instance serves both roles, aggregate statistics conflate two fundamentally different signal profiles. A cache miss spike on the recursive side elevates RecursClients and outbound query rate, but those counters are irrelevant to the authoritative path. An authoritative zone failing to load produces SERVFAIL for that zone, but on a mixed-role server, that signal is buried under recursive traffic noise.
Teams running mixed-role BIND monitor aggregate statistics and miss zone-specific authoritative failures. Per-view monitoring is essential if both roles must share one instance. Better to separate them into different server sets so the failure domains do not overlap.
This masking effect extends to other deployment variants. Anycast deployments can hide per-node saturation behind stable global aggregates. Split-horizon setups produce failures that look different depending on the source IP, which aggregate stats never catch. Hidden primaries never receive direct queries, so query-volume monitoring is useless for them. Transfer health and zone serial consistency are the only signals that matter for secondaries and hidden primaries.
Signals to watch in production
| Signal | Why it matters | Warning sign |
|---|---|---|
RecursClients (gauge, not counter) | Approaching the recursive-clients limit means imminent cliff-edge SERVFAIL | Sustained above 50% of limit; soft quota at 90% |
QrySERVFAIL ratio | SERVFAIL means BIND failed to complete the work. Server can appear up while returning 100% SERVFAIL | Above 0.1% of classified responses |
Cache hit ratio (CacheHits / (CacheHits + CacheMisses)) | Low hit ratio drives more upstream queries, compounding load | Drop below baseline after warmup period |
RcvbufErrors (/proc/net/snmp, UDP line) | Packets dropped by kernel before BIND sees them. Invisible to all BIND counters | Any sustained non-zero rate |
| SOA serial consistency | Secondary serving stale data, approaching expiry cliff | Serial mismatch persisting beyond refresh interval |
ValFail (per-view resolver stat) | DNSSEC validation failures produce SERVFAIL for signed domains | Any sustained increase from near-zero baseline |
| Process RSS | Memory growth toward OOM kill | Steady climb after warmup plateau |
How Netdata helps
Netdata’s BIND collector pulls from the statistics channel and the OS level, correlating signals that are normally scattered across different tools:
- Per-second resolution on
RecursClientsas a percentage of the configured limit, so the soft-quota threshold and the hard cliff are visible as a trend, not just a point-in-time snapshot. QrySERVFAILrate computed automatically from cumulative counters, so the ratio is visible without manual delta math against raw counters.- Cache hit ratio derived from per-view
CacheHitsandCacheMisses, correlated withRecursClientsand upstream RTT buckets in the same dashboard. - Kernel UDP receive errors from
/proc/net/snmp, collected at the OS level and overlaid against BIND query rate, closing the most common monitoring blind spot. - ML-based anomaly detection on response code distribution and query rate patterns, surfacing gradual degradation that binary health checks miss.
Related guides
- BIND monitoring checklist: the signals every production resolver and authoritative server needs
- BIND monitoring maturity model: from survival to expert
- BIND SERVFAIL responses: what a DNS SERVFAIL actually means and how to trace the cause
- BIND REFUSED responses: ACL denials, recursion policy, and clients that get locked out
- named not responding on port 53: total outage versus UDP-works-TCP-fails
- BIND NXDOMAIN spike: DGA malware, water torture, and Windows suffix search lists
- rndc not responding: control-plane failure while queries still work
- BIND ’no more recursive clients: quota reached’: the recursive-clients circuit breaker
- BIND RecursClients climbing toward the limit: reading the recursive saturation gauge
- BIND recursive resolution cascade: one slow upstream taking down all resolution
- BIND forwarding loops: recursion that never terminates and burns recursive slots
- BIND resolver NumFetch per view: per-view recursive pressure in split-horizon setups






