<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>CoreDNS Operations Guides on Netdata</title><link>https://www.netdata.cloud/guides/coredns/</link><description>Recent content in CoreDNS Operations Guides on Netdata</description><generator>Hugo</generator><language>en-us</language><atom:link href="https://www.netdata.cloud/guides/coredns/index.xml" rel="self" type="application/rss+xml"/><item><title>CoreDNS /health vs /ready: the readiness-probe mistake that serves SERVFAIL</title><link>https://www.netdata.cloud/guides/coredns/coredns-health-vs-ready-probe/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-health-vs-ready-probe/</guid><description>&lt;p>Your CoreDNS pods look healthy. Liveness passes, readiness passes, the pods are Running and Ready. Yet for the first seconds or minutes after every pod start, clients get SERVFAIL for &lt;code>cluster.local&lt;/code> names. New deployments fail to resolve their dependencies, retries pile up, and then the problem vanishes on its own.&lt;/p>
&lt;p>This is the classic symptom of pointing the Kubernetes readiness probe at &lt;code>/health&lt;/code> instead of &lt;code>/ready&lt;/code>. The two endpoints answer different questions, and confusing them makes your readiness gate meaningless.&lt;/p></description></item><item><title>CoreDNS 403 from the Kubernetes API: RBAC misconfiguration breaking cluster DNS</title><link>https://www.netdata.cloud/guides/coredns/coredns-rbac-403-api-errors/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-rbac-403-api-errors/</guid><description>&lt;p>The symptom usually arrives in one of two forms. Either CoreDNS pods never become ready after an install or upgrade, stuck at 0/1 while &lt;code>kubectl&lt;/code> shows no crash and no obvious error, or cluster DNS suddenly returns SERVFAIL for &lt;code>cluster.local&lt;/code> names while external resolution keeps working. In both cases, the smoking gun is the same: &lt;code>coredns_kubernetes_rest_client_requests_total{code=&amp;quot;403&amp;quot;}&lt;/code> is incrementing.&lt;/p>
&lt;p>A 403 from the Kubernetes API is not a transient error. It means the API server received the request, authenticated the caller, and refused it because the CoreDNS ServiceAccount lacks the RBAC permissions the kubernetes plugin needs to list and watch Services, Endpoints, and EndpointSlices. Without those watches, the plugin cannot build or maintain its in-memory record set, so it cannot answer queries for the cluster zone.&lt;/p></description></item><item><title>CoreDNS 5-second DNS timeout: the Kubernetes glibc A+AAAA conntrack race</title><link>https://www.netdata.cloud/guides/coredns/coredns-5-second-dns-timeout/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-5-second-dns-timeout/</guid><description>&lt;p>Your application latency histogram has a cluster of samples at almost exactly 5 seconds. Not 4.8, not 5.3: a tight spike right at the glibc default resolver timeout. Tracing the slow calls shows they stall on name resolution. CoreDNS dashboards are green: low latency, no SERVFAIL, healthy cache hit ratio, both replicas fine.&lt;/p>
&lt;p>That combination, application-side DNS stalls at exactly the resolver timeout with clean CoreDNS metrics, is the signature of the glibc A+AAAA conntrack race. The loss is in the kernel network path between the application pod and CoreDNS, not inside CoreDNS. No amount of Corefile tuning will touch it.&lt;/p></description></item><item><title>CoreDNS all upstreams down: the forwarding black hole and healthcheck_broken</title><link>https://www.netdata.cloud/guides/coredns/coredns-all-upstreams-down/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-all-upstreams-down/</guid><description>&lt;p>Every forwarded query through CoreDNS is suddenly returning SERVFAIL, request latency has dropped instead of rising, and &lt;code>coredns_forward_healthcheck_broken_total&lt;/code> is climbing. This is the upstream black hole: every upstream resolver configured in the &lt;code>forward&lt;/code> plugin is failing health checks at the same time, and CoreDNS has nowhere to send external queries.&lt;/p>
&lt;p>The counter-intuitive part is the latency profile. When upstreams die hard, failures are fast. Queries do not sit in timeouts the way they do with a slow upstream. If you only alert on high latency, this failure mode sails under your dashboards until clients start reporting resolution errors.&lt;/p></description></item><item><title>CoreDNS ANY query flood: DNS amplification and reflection abuse</title><link>https://www.netdata.cloud/guides/coredns/coredns-any-query-amplification/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-any-query-amplification/</guid><description>&lt;p>You are looking at &lt;code>coredns_dns_requests_total&lt;/code> and the &lt;code>type=&amp;quot;ANY&amp;quot;&lt;/code> series has jumped from a flat zero to a sustained rate, or ANY queries have crept past a few percent of total traffic. That pattern is the classic fingerprint of DNS amplification and reflection abuse: an attacker sends small ANY queries with a spoofed source address, and your CoreDNS replies with large responses delivered to the victim&amp;rsquo;s IP. Your server is the reflector; someone else absorbs the blast.&lt;/p></description></item><item><title>CoreDNS AXFR zone transfer attempts: reconnaissance of internal service topology</title><link>https://www.netdata.cloud/guides/coredns/coredns-axfr-zone-transfer-attempts/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-axfr-zone-transfer-attempts/</guid><description>&lt;p>An AXFR query asks a DNS server for the entire contents of a zone: every record, not one. Against a Kubernetes cluster running CoreDNS, a successful zone transfer hands the requester a complete map of internal service topology: every Service name, every namespace, every headless Service endpoint, every pod hostname you publish. That is exactly the map an attacker wants before lateral movement.&lt;/p>
&lt;p>Stock CoreDNS does not serve AXFR. Unless the &lt;code>transfer&lt;/code> plugin is explicitly configured in the Corefile, zone transfer requests are refused, and default kubeadm, EKS, GKE, and AKS Corefiles do not include it. In a typical deployment, an AXFR query is not a data-loss event. It is a tripwire.&lt;/p></description></item><item><title>CoreDNS cache collapse: the cold-cache thundering herd after a rollout</title><link>https://www.netdata.cloud/guides/coredns/coredns-cache-collapse-thundering-herd/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-cache-collapse-thundering-herd/</guid><description>&lt;p>You just rolled out a CoreDNS config change or image bump. Within seconds, DNS latency across the cluster jumps, upstream DNS traffic spikes to several times baseline, and SERVFAILs appear in application logs. One to five minutes later, it all goes away on its own. The dashboard is green again.&lt;/p>
&lt;p>That is the cache collapse pattern: every CoreDNS pod restarted at roughly the same time, every in-memory cache emptied at once, and every client in the cluster re-queried the same names simultaneously. The flood hit your upstreams harder than they could absorb. In the worst version, upstreams return SERVFAIL, CoreDNS caches those SERVFAILs for 5 seconds each, and a brief overload amplifies into a visible outage.&lt;/p></description></item><item><title>CoreDNS cache evictions: the cache is too small for the working set</title><link>https://www.netdata.cloud/guides/coredns/coredns-cache-evictions-undersized/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-cache-evictions-undersized/</guid><description>&lt;p>&lt;code>coredns_cache_evictions_total&lt;/code> climbing steadily, or upstream query load and DNS latency creeping up without any change in traffic volume, both point at the same thing: the cache plugin is evicting entries before their TTL expires because it has run out of room, and queries that should have been sub-millisecond cache hits are being forwarded to upstream resolvers instead.&lt;/p>
&lt;p>This is progressive degradation, not a cliff edge. Latency rises, upstream load rises, and the hit ratio slides, slowly enough that it often goes unnoticed until someone asks why DNS got slower this quarter.&lt;/p></description></item><item><title>CoreDNS cache hit ratio dropping: latency and upstream load climbing together</title><link>https://www.netdata.cloud/guides/coredns/coredns-cache-hit-ratio-dropping/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-cache-hit-ratio-dropping/</guid><description>&lt;p>The cache hit ratio is &lt;code>coredns_cache_hits_total / coredns_cache_requests_total&lt;/code>. When it falls, every query that used to be answered from memory in under a millisecond now goes to the kubernetes plugin or out to an upstream resolver. Two things happen at once: &lt;code>coredns_dns_request_duration_seconds&lt;/code> climbs, and forwarded query volume climbs with it. That second effect is the dangerous one, because the upstream flood can degrade the upstreams themselves and turn a cache problem into a resolution outage.&lt;/p></description></item><item><title>CoreDNS conntrack table full: silent UDP packet drops with a node-wide blast radius</title><link>https://www.netdata.cloud/guides/coredns/coredns-conntrack-table-full/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-conntrack-table-full/</guid><description>&lt;p>Applications across a node start timing out on DNS lookups. Then on database connections. Then on API calls. You check CoreDNS and the dashboards are green: low latency, no SERVFAILs, healthy pods. But the timeouts keep coming, and they are not limited to DNS.&lt;/p>
&lt;p>This is conntrack table exhaustion. Every UDP DNS query that traverses Kubernetes iptables DNAT creates a connection tracking entry on the node with a default timeout of 30 seconds. At high DNS QPS, the table fills. When it does, the kernel drops new packets silently: no ICMP error, no reset, no log line the application will ever see. The kernel log says &lt;code>nf_conntrack: table full, dropping packet&lt;/code> and nothing else anywhere warns you.&lt;/p></description></item><item><title>CoreDNS Corefile parse error: startup failures and invalid plugin config</title><link>https://www.netdata.cloud/guides/coredns/coredns-corefile-parse-error/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-corefile-parse-error/</guid><description>&lt;p>You changed the Corefile, and now one of two things has happened. Either the CoreDNS pods are in CrashLoopBackOff and cluster DNS is down, or the pods look fine but your change never took effect and the log is full of parse errors. Both are the same root event: the Corefile parser rejected your configuration. The difference is whether the parser ran at process start (fatal) or during a live reload (rejected, old config kept).&lt;/p></description></item><item><title>CoreDNS CPU throttling: CFS limits making a green dashboard lie about latency</title><link>https://www.netdata.cloud/guides/coredns/coredns-cpu-throttling-slow-responses/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-cpu-throttling-slow-responses/</guid><description>&lt;p>Applications are reporting intermittent DNS timeouts and multi-hundred-millisecond resolution spikes. You open the CoreDNS dashboard and everything looks fine: &lt;code>coredns_dns_request_duration_seconds&lt;/code> shows sub-millisecond cache hits, SERVFAIL is zero, QPS is normal, pods are healthy. Both things are true at the same time, and that is exactly the problem.&lt;/p>
&lt;p>When a CoreDNS pod has a tight CPU limit, the Linux CFS scheduler throttles the container: the process is runnable but the kernel refuses to schedule it until the next quota period. That stall is real latency for the client, but it never appears in any CoreDNS metric, because CoreDNS only measures time spent actively processing a query. Time spent waiting for CPU does not exist as far as &lt;code>coredns_dns_request_duration_seconds&lt;/code> is concerned.&lt;/p></description></item><item><title>CoreDNS CrashLoopBackOff: triaging loop, OOM, config, and port-bind causes</title><link>https://www.netdata.cloud/guides/coredns/coredns-crashloopbackoff-triage/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-crashloopbackoff-triage/</guid><description>&lt;p>A CoreDNS pod in CrashLoopBackOff means the process starts, dies, and gets restarted by Kubernetes in a tightening backoff loop. While this is happening, at least one DNS replica is contributing nothing. If all replicas are crash-looping, the &lt;code>kube-dns&lt;/code> Service has no backends and cluster-wide name resolution is down: queries hang at the client until a pod recovers.&lt;/p>
&lt;p>CrashLoopBackOff is not one failure. It is a symptom with a small set of common root causes, and they need different fixes. The four you will see most often: the loop plugin detecting a forwarding loop, the OOM killer terminating the container, a Corefile that fails to parse, and a port-bind failure on startup. RBAC and Kubernetes API access failures show up in the same pod state too, usually as fatal list errors or persistent un-readiness.&lt;/p></description></item><item><title>CoreDNS DNS programming latency: how long a Service takes to become resolvable</title><link>https://www.netdata.cloud/guides/coredns/coredns-dns-programming-duration/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-dns-programming-duration/</guid><description>&lt;p>You create a Service, the API server accepts it, &lt;code>kubectl get svc&lt;/code> shows it, and yet for some period of time nothing in the cluster can resolve its name. That gap, from &amp;ldquo;the object exists in the API&amp;rdquo; to &amp;ldquo;CoreDNS answers for it&amp;rdquo;, is DNS programming latency, and CoreDNS exposes it as a first-class metric: &lt;code>coredns_kubernetes_dns_programming_duration_seconds&lt;/code>.&lt;/p>
&lt;p>This is the Kubernetes DNS Programming SLI. It exists because service discovery delay is a real failure mode: a rollout completes, endpoints are ready, but clients still get NXDOMAIN or stale answers for seconds or tens of seconds. From the application&amp;rsquo;s perspective the new pods are unreachable by name. From CoreDNS&amp;rsquo;s request metrics everything looks green.&lt;/p></description></item><item><title>CoreDNS forward max_concurrent rejects: the forward plugin is overwhelmed</title><link>https://www.netdata.cloud/guides/coredns/coredns-forward-max-concurrent-rejects/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-forward-max-concurrent-rejects/</guid><description>&lt;p>&lt;code>coredns_forward_max_concurrent_rejects_total&lt;/code> is incrementing and clients are getting REFUSED responses for forwarded queries. Something is piling up between CoreDNS and your upstreams, and the rejects are the valve letting pressure escape.&lt;/p>
&lt;p>This counter only increments when the number of in-flight forwarded queries hits the &lt;code>max_concurrent&lt;/code> cap you configured. Every rejected query gets a REFUSED response, not SERVFAIL. That distinction matters for triage: REFUSED from this path is a capacity signal, not a resolution failure, and unlike NXDOMAIN it is not subject to negative caching, so it will not linger in client caches after the pressure clears.&lt;/p></description></item><item><title>CoreDNS GC pauses adding tail latency: go_gc_duration_seconds and heap pressure</title><link>https://www.netdata.cloud/guides/coredns/coredns-gc-pause-tail-latency/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-gc-pause-tail-latency/</guid><description>&lt;p>Your CoreDNS dashboards look mostly fine: P50 latency is sub-millisecond, SERVFAIL is zero, cache hit ratio is healthy. But P99 is spiking to tens or hundreds of milliseconds at irregular intervals, and a small fraction of clients see DNS timeouts they cannot explain. The process never crashes. Upstream latency is clean. CPU looks acceptable on average.&lt;/p>
&lt;p>This is the classic signature of Go garbage collection stop-the-world pauses landing on DNS query latency. CoreDNS is a Go process, and every in-flight query is a goroutine. When the GC stops the world, every one of those goroutines waits. DNS is supposed to be sub-millisecond for cache hits, so a pause that would be invisible in a batch service is user-visible here. The working threshold: GC pauses over 10ms are impactful for DNS and show up as P99 spikes.&lt;/p></description></item><item><title>CoreDNS goroutine count climbing: blocked upstream calls and leaks</title><link>https://www.netdata.cloud/guides/coredns/coredns-goroutine-leak/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-goroutine-leak/</guid><description>&lt;p>Your &lt;code>go_goroutines&lt;/code> graph for CoreDNS is trending up. Maybe it spiked during an incident and never came back down. Maybe it has been climbing slowly for days. Either way, the question is the same: are queries piling up behind a slow upstream, or is something leaking goroutines that will never exit?&lt;/p>
&lt;p>The distinction matters because the fixes are completely different. A blocked-upstream spike resolves when the upstream recovers. A leak grows until the OOM killer ends the debate for you.&lt;/p></description></item><item><title>CoreDNS high request latency: reading P99 by zone to find the cause</title><link>https://www.netdata.cloud/guides/coredns/coredns-high-request-latency-p99/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-high-request-latency-p99/</guid><description>&lt;p>P99 on &lt;code>coredns_dns_request_duration_seconds&lt;/code> is at 400ms when it used to sit at 15ms. Do not start with the aggregate number: aggregate latency in CoreDNS blends at least two very different workloads. Cache hits should complete in single-digit milliseconds. Forwarded and Kubernetes-backed queries depend on systems outside CoreDNS itself.&lt;/p>
&lt;p>The &lt;code>zone&lt;/code> label on the duration histogram is the fork in the road. High latency in &lt;code>cluster.local&lt;/code> points at the Kubernetes path. High latency in forwarded zones points at upstream resolvers. High latency everywhere, at every percentile, points at the CoreDNS process itself: CPU saturation or GC pressure. Until you split the histogram by zone, you are guessing.&lt;/p></description></item><item><title>CoreDNS Kubernetes API disconnect: stale records and new services going invisible</title><link>https://www.netdata.cloud/guides/coredns/coredns-kubernetes-api-disconnect/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-kubernetes-api-disconnect/</guid><description>&lt;p>The symptom that usually surfaces first is not a DNS error. It is a developer saying &amp;ldquo;I deployed the service twenty minutes ago and nothing can reach it,&amp;rdquo; while every existing workload looks fine. &lt;code>nslookup kubernetes.default&lt;/code> works. External domains resolve. CoreDNS dashboards are green. But anything created or changed recently in the cluster does not exist as far as DNS is concerned.&lt;/p>
&lt;p>This is the Kubernetes API disconnect pattern. The CoreDNS kubernetes plugin maintains its DNS records by watching the API server through informers, not by querying the API per DNS request. When that watch breaks and cannot reconnect, CoreDNS keeps answering from its last known in-memory snapshot. Existing services keep resolving, which is exactly why the failure is so dangerous: everything looks healthy while the answers drift further from reality.&lt;/p></description></item><item><title>CoreDNS Loop detected and CrashLoopBackOff: the forwarding loop that kills the pod</title><link>https://www.netdata.cloud/guides/coredns/coredns-loop-detected-crashloopbackoff/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-loop-detected-crashloopbackoff/</guid><description>&lt;p>Your CoreDNS pods are in CrashLoopBackOff. &lt;code>kubectl logs&lt;/code> shows a line like &lt;code>[FATAL] plugin/loop: Loop (127.0.0.1:53 -&amp;gt; :53) detected for zone &amp;quot;.&amp;quot;&lt;/code>, and the process exits a few seconds after every start. There are no CoreDNS metrics to look at, because the process dies before the metrics endpoint is ever scraped.&lt;/p>
&lt;p>The crash is intentional. The &lt;code>loop&lt;/code> plugin detected that the Corefile&amp;rsquo;s &lt;code>forward&lt;/code> target routes queries back to CoreDNS itself, and it killed the process on purpose to prevent an infinite query amplification storm. Kubernetes restarts the pod, the loop is detected again, and the cycle repeats.&lt;/p></description></item><item><title>CoreDNS memory climbing: heap growth, post-GC minima, and leak detection</title><link>https://www.netdata.cloud/guides/coredns/coredns-memory-leak-heap-growth/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-memory-leak-heap-growth/</guid><description>&lt;p>CoreDNS memory has been creeping up for hours. The Grafana panel shows a sawtooth that never quite comes back down, and you need to answer one question before the pod gets OOMKilled: is this Go being Go, or is something actually leaking?&lt;/p>
&lt;p>The trap is that &lt;code>go_memstats_heap_inuse_bytes&lt;/code> is spiky by design. The heap grows, the garbage collector reclaims, the heap grows again. If you react to instantaneous peaks you will chase ghosts all night. The signal that separates normal GC behavior from a leak is the trend of the post-GC minima: the floor each sawtooth returns to. If that floor keeps rising over an hour or more and never returns to baseline, you have a genuine leak heading for the container memory limit.&lt;/p></description></item><item><title>CoreDNS memory limit and the re-list spike: sizing for the restart peak</title><link>https://www.netdata.cloud/guides/coredns/coredns-memory-limit-relist-spike/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-memory-limit-relist-spike/</guid><description>&lt;p>A CoreDNS pod that runs fine for weeks gets OOMKilled thirty seconds after a restart. Kubernetes starts it again. It re-syncs, allocates heavily, crosses the limit, and gets killed again. Restart count climbs into the hundreds, and cluster DNS capacity drops by half or more while the crash loop runs. &lt;code>kubectl describe pod&lt;/code> shows &lt;code>Last State: Terminated, Reason: OOMKilled&lt;/code>, and nothing in steady-state monitoring predicted it.&lt;/p>
&lt;p>The mechanism: the memory limit was sized against steady-state RSS, but the kubernetes plugin&amp;rsquo;s startup re-list is the actual peak memory event in CoreDNS&amp;rsquo;s lifecycle. In large clusters that peak runs 2-3x steady state. A limit set 10-20% above normal RSS is a limit sized to guarantee a crash loop on the next restart.&lt;/p></description></item><item><title>CoreDNS monitoring checklist: the signals every production resolver needs</title><link>https://www.netdata.cloud/guides/coredns/coredns-monitoring-checklist/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-monitoring-checklist/</guid><description>&lt;p>CoreDNS has one failure mode that defeats most monitoring setups: a pod that passes every health probe while returning SERVFAIL for every query. The &lt;code>/health&lt;/code> endpoint on port 8080 checks process liveness. It does not test DNS resolution. The &lt;code>/ready&lt;/code> endpoint on port 8181 is plugin-aware, but it does not test resolution either. Teams that alert on pod status and probe results are monitoring the wrong thing.&lt;/p>
&lt;p>The actual availability signal for a DNS server is the RCODE distribution of its responses, primarily &lt;code>coredns_dns_responses_total{rcode=&amp;quot;SERVFAIL&amp;quot;}&lt;/code>. Everything else exists to explain and predict changes in that signal.&lt;/p></description></item><item><title>CoreDNS monitoring maturity model: from survival to expert</title><link>https://www.netdata.cloud/guides/coredns/coredns-monitoring-maturity-model/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-monitoring-maturity-model/</guid><description>&lt;p>Most CoreDNS monitoring setups are either a single &amp;ldquo;is the pod up&amp;rdquo; check or a wall of dashboards nobody reads during an incident. Neither works. The right question is not &amp;ldquo;how many metrics do we collect&amp;rdquo; but &amp;ldquo;which failure modes can we actually detect right now.&amp;rdquo; That is what a maturity model answers: it orders signals by the failures they catch, so you can see exactly which class of outage would currently reach your users before it reaches your alerts.&lt;/p></description></item><item><title>CoreDNS ndots:5 query amplification: one lookup becoming five</title><link>https://www.netdata.cloud/guides/coredns/coredns-ndots-search-domain-amplification/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-ndots-search-domain-amplification/</guid><description>&lt;p>CoreDNS dashboards show 50,000 QPS, the denial cache is churning, and NXDOMAIN responses are a third of all traffic, but nothing is broken. What you are looking at is probably not real demand. The default &lt;code>ndots:5&lt;/code> in every pod&amp;rsquo;s &lt;code>/etc/resolv.conf&lt;/code> expands each external lookup through the Kubernetes search domain list, so one logical lookup becomes four to six wire queries before the real name is ever tried.&lt;/p>
&lt;p>Teams routinely misread this. They see amplified QPS, assume 50,000 lookups per second of genuine demand, and capacity-plan, scale, and alarm against a number inflated 4-6x. A rule of thumb: 50,000 QPS at CoreDNS often represents only 8,000 to 12,000 logical application lookups.&lt;/p></description></item><item><title>CoreDNS NOERROR with zero answers: the resolution failure that reports success</title><link>https://www.netdata.cloud/guides/coredns/coredns-noerror-empty-answers/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-noerror-empty-answers/</guid><description>&lt;p>Your RCODE dashboards are green. NOERROR rate is healthy, SERVFAIL is near zero, health probes pass. Yet an application team reports their service cannot resolve a dependency. &lt;code>dig&lt;/code> returns instantly with &lt;code>status: NOERROR&lt;/code> and &lt;code>ANSWER SECTION: 0&lt;/code>. No address, no error, no timeout. The resolver library treats this as &amp;ldquo;the name exists but has no records&amp;rdquo; and the application fails with a connection error that looks nothing like a DNS problem.&lt;/p></description></item><item><title>CoreDNS not resolving external domains: the missing catch-all forward zone</title><link>https://www.netdata.cloud/guides/coredns/coredns-external-domains-not-resolving/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-external-domains-not-resolving/</guid><description>&lt;p>The symptom is specific: names inside the cluster resolve, but anything outside the cluster fails. &lt;code>kubernetes.default.svc.cluster.local&lt;/code> works. &lt;code>example.com&lt;/code> does not. Applications report DNS timeouts, &lt;code>getaddrinfo&lt;/code> failures, or intermittent external dependency errors while service discovery inside Kubernetes looks fine.&lt;/p>
&lt;p>That split is the clue. CoreDNS is not one global resolver. It matches each query to the most specific server block in the Corefile, then runs that block&amp;rsquo;s plugin chain. If &lt;code>cluster.local&lt;/code> is handled by the &lt;code>kubernetes&lt;/code> plugin but there is no catch-all block for &lt;code>.&lt;/code>, external names match nothing useful and are refused instead of forwarded.&lt;/p></description></item><item><title>CoreDNS NXDOMAIN flood from one source: DGA malware and domain enumeration</title><link>https://www.netdata.cloud/guides/coredns/coredns-nxdomain-flood-dga/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-nxdomain-flood-dga/</guid><description>&lt;p>Your CoreDNS dashboards are green: SERVFAIL is zero, latency is fine, cache hit ratio looks normal. But the NXDOMAIN rate has jumped, and when you pull query logs, one source IP is responsible for thousands of NXDOMAIN responses per hour, querying names that do not exist.&lt;/p>
&lt;p>This is a security signal, not a CoreDNS health signal. A single source generating a sustained flood of NXDOMAIN responses is doing one of three things: cycling randomly generated domains looking for a command-and-control server (DGA malware in a compromised pod), probing which service names exist in your cluster (reconnaissance), or misbehaving in a way that merely looks like an attack (a config typo hammering a name that was never created).&lt;/p></description></item><item><title>CoreDNS NXDOMAIN vs SERVFAIL: why alerting on the wrong one buries real incidents</title><link>https://www.netdata.cloud/guides/coredns/coredns-nxdomain-vs-servfail/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-nxdomain-vs-servfail/</guid><description>&lt;p>Your CoreDNS alert fired again. The &amp;ldquo;DNS error rate&amp;rdquo; panel shows a wall of red, so you open it, see a pile of NXDOMAIN responses, and silence the alert. Meanwhile, a genuine upstream failure is producing SERVFAIL responses somewhere in that same wall of red, and nobody will notice until an application team opens a ticket.&lt;/p>
&lt;p>This is the most common CoreDNS alerting mistake: treating all non-NOERROR responses as one bucket. NXDOMAIN and SERVFAIL look similar in a naive error counter, but they mean opposite things. NXDOMAIN is the server correctly reporting that a name does not exist. SERVFAIL is the server admitting it failed to answer at all. Alerting on the sum of both guarantees that the noise (NXDOMAIN, constant and expected in Kubernetes) drowns the signal (SERVFAIL, rare and always actionable).&lt;/p></description></item><item><title>CoreDNS OOMKilled: the memory cliff and the restart crash loop</title><link>https://www.netdata.cloud/guides/coredns/coredns-oomkilled/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-oomkilled/</guid><description>&lt;p>You found the CoreDNS pods in &lt;code>kube-system&lt;/code> with &lt;code>OOMKilled&lt;/code> as the last terminated state. Maybe one pod restarted once and recovered. Maybe both replicas are flapping and cluster DNS is degraded or down. Either way, the pod status operators paste into a search bar is the same: &lt;code>Last State: Terminated, Reason: OOMKilled&lt;/code>.&lt;/p>
&lt;p>Memory exhaustion in CoreDNS is a cliff edge, not a slowdown. There is no degradation curve where latency rises and errors climb while you watch. RSS approaches the container memory limit, the kernel OOM killer terminates the process instantly, and every client served by that pod loses DNS until a replacement is ready. The warning phase exists only in your metrics, and only if you are watching the right ones.&lt;/p></description></item><item><title>CoreDNS panics: recovered handler crashes and coredns_panics_total</title><link>https://www.netdata.cloud/guides/coredns/coredns-panics-recovered/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-panics-recovered/</guid><description>&lt;p>You found &lt;code>coredns_panics_total&lt;/code> above zero, or you saw &lt;code>Recovered from panic&lt;/code> in the CoreDNS logs. The pods are not restarting, the health endpoint returns 200, and most DNS queries still resolve. That combination is what makes this failure mode easy to ignore and dangerous to dismiss.&lt;/p>
&lt;p>A recovered panic means a query handler crashed inside the plugin chain and CoreDNS&amp;rsquo;s recovery wrapper caught it, keeping the process alive. The server survived. The query that triggered the panic did not: the client that sent it got no answer and waited out its own timeout. Every increment of the counter is a real query that failed, plus evidence of a genuine bug in CoreDNS or one of its plugins.&lt;/p></description></item><item><title>CoreDNS per-replica divergence: why averaged metrics hide a failing pod</title><link>https://www.netdata.cloud/guides/coredns/coredns-per-replica-divergence/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-per-replica-divergence/</guid><description>&lt;p>Your CoreDNS dashboard looks slightly off. Average latency drifted up, SERVFAIL ratio is elevated but under the threshold, and nobody is being paged. Meanwhile, half the cluster&amp;rsquo;s DNS queries are slow or failing, because one of your two replicas is degraded and kube-proxy is still sending it traffic.&lt;/p>
&lt;p>This is the per-replica divergence failure mode. CoreDNS in Kubernetes is almost never a singleton: the default deployment runs two replicas behind the &lt;code>kube-dns&lt;/code> ClusterIP Service, and kube-proxy load-balances across them. Any aggregation that averages or sums across pods blends a sick replica&amp;rsquo;s numbers with healthy ones until the result looks like mild degradation instead of a partial outage.&lt;/p></description></item><item><title>CoreDNS per-upstream health check failures: degraded redundancy before total loss</title><link>https://www.netdata.cloud/guides/coredns/coredns-per-upstream-health-check-failures/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-per-upstream-health-check-failures/</guid><description>&lt;p>One of your upstream DNS resolvers is failing CoreDNS&amp;rsquo;s health checks. Queries are still being answered because the remaining upstreams are carrying the forwarding load, so nothing is paging yet. This is exactly the window you want: degraded redundancy, not an outage. The next failure in this sequence is &lt;code>coredns_forward_healthcheck_broken_total&lt;/code> incrementing, at which point every upstream is marked unhealthy and you are in a real incident.&lt;/p>
&lt;p>The signal is &lt;code>coredns_proxy_healthcheck_failures_total&lt;/code>, a counter in the proxy subsystem. Filter it by &lt;code>proxy_name=&amp;quot;forward&amp;quot;&lt;/code> and read the &lt;code>to&lt;/code> label: it names the specific upstream address that is failing. That label is the whole point of this metric. It turns &amp;ldquo;forwarding is degraded&amp;rdquo; into &amp;ldquo;10.0.0.2:53 is the problem.&amp;rdquo;&lt;/p></description></item><item><title>CoreDNS pod alive but not ready: the /ready endpoint and API sync</title><link>https://www.netdata.cloud/guides/coredns/coredns-readiness-probe-not-ready/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-readiness-probe-not-ready/</guid><description>&lt;p>The pod is &lt;code>Running&lt;/code>. The process is up, the logs show CoreDNS started, maybe it is even answering some queries. But &lt;code>kubectl get pods -n kube-system&lt;/code> shows &lt;code>0/1 READY&lt;/code>, the pod is excluded from the &lt;code>kube-dns&lt;/code> Service endpoints, and your cluster is running on one fewer DNS replica than you think. If this is your only replica, or the other one is on the same node, you are one hiccup away from a cluster-wide DNS outage.&lt;/p></description></item><item><title>CoreDNS query rate dropped to zero while the process looks healthy</title><link>https://www.netdata.cloud/guides/coredns/coredns-query-rate-dropped-to-zero/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-query-rate-dropped-to-zero/</guid><description>&lt;p>The dashboard shows &lt;code>coredns_dns_requests_total&lt;/code> flatlined at zero. You check the pod: &lt;code>Running&lt;/code>, zero restarts. &lt;code>/health&lt;/code> on port 8080 returns 200. The process is fine. So either nobody in the cluster is resolving names anymore, or the traffic is dying somewhere between your clients and the CoreDNS process, and CoreDNS has no idea.&lt;/p>
&lt;p>The second possibility is the trap. CoreDNS only counts queries it actually receives. A UDP packet dropped by the kernel before it reaches the CoreDNS socket is never counted, never logged, and never reflected in any CoreDNS metric. A full conntrack table, an overflowing UDP receive buffer, a network policy isolating the pod, or a readiness failure that pulled the pod out of the Service endpoints all look identical in CoreDNS metrics: nothing.&lt;/p></description></item><item><title>CoreDNS reload failed: config drift when the new Corefile never took effect</title><link>https://www.netdata.cloud/guides/coredns/coredns-reload-failed/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-reload-failed/</guid><description>&lt;p>You pushed a Corefile change, nothing broke, and everyone moved on. Weeks later you discover the cluster is still running the old configuration. The metric that would have told you is &lt;code>coredns_reload_failed_total&lt;/code>, and it was nonzero the whole time.&lt;/p>
&lt;p>A failed CoreDNS reload is not an outage. The &lt;code>reload&lt;/code> plugin polls the Corefile every 30 seconds (with jitter) and triggers a graceful reload when the SHA512 checksum of the file changes. If the new configuration has a syntax error, an invalid plugin directive, or hits a port conflict, CoreDNS logs the error, increments &lt;code>coredns_reload_failed_total&lt;/code>, and keeps serving DNS with the old config. Queries keep flowing. The only thing that changed is that reality and your intent have quietly diverged.&lt;/p></description></item><item><title>CoreDNS response size distribution: large answers, TCP pressure, and amplification</title><link>https://www.netdata.cloud/guides/coredns/coredns-large-response-size/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-large-response-size/</guid><description>&lt;p>Most CoreDNS dashboards track QPS, latency, and SERVFAIL. Response size rarely makes the cut until something odd happens: TCP/53 traffic climbs for no obvious reason, a workload starts resolving incomplete answers, or a security review asks whether your resolvers could be used as DDoS reflectors. All three questions are answered by the same signal: the distribution of DNS response sizes CoreDNS is sending.&lt;/p>
&lt;p>The metric is &lt;code>coredns_dns_response_size_bytes&lt;/code>, a histogram exported by the prometheus plugin with labels &lt;code>server&lt;/code>, &lt;code>zone&lt;/code>, &lt;code>view&lt;/code>, and &lt;code>proto&lt;/code> (udp/tcp). This article covers what a healthy distribution looks like, what pushes it toward large answers, why large answers create TCP pressure, and how to separate benign large record sets from amplification abuse using the labels you already have. It is a reference for interpreting the signal; the related guides at the end cover the concrete failure modes.&lt;/p></description></item><item><title>CoreDNS response truncation: the TC bit, EDNS bufsize, and TCP fallback</title><link>https://www.netdata.cloud/guides/coredns/coredns-response-truncation-tcp-fallback/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-response-truncation-tcp-fallback/</guid><description>&lt;p>Most DNS traffic fits in a single UDP datagram. When it does not, the protocol has an escape hatch: the server sets the TC (truncated) bit in the response, and the client retries the same query over TCP. CoreDNS implements this correctly in the common case, but the edges are where production incidents live: firewalls that silently block TCP/53, legacy clients that do not speak EDNS0, and known CoreDNS bugs where the TC flag never reaches the client at all.&lt;/p></description></item><item><title>CoreDNS returning REFUSED: no matching zone, an ACL, or the forward concurrency limit</title><link>https://www.netdata.cloud/guides/coredns/coredns-refused-responses/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-refused-responses/</guid><description>&lt;p>CoreDNS is answering queries with &lt;code>REFUSED&lt;/code> and clients cannot resolve names. Unlike SERVFAIL, which means &amp;ldquo;I tried and failed,&amp;rdquo; REFUSED means &amp;ldquo;I declined to try.&amp;rdquo; REFUSED is almost never an upstream or network problem: CoreDNS itself is deciding not to answer, and it does that for exactly three reasons.&lt;/p>
&lt;p>Two are configuration problems: no server block matches the query&amp;rsquo;s zone, or the &lt;code>acl&lt;/code> plugin is rejecting the source. One is a capacity problem: the &lt;code>forward&lt;/code> plugin&amp;rsquo;s &lt;code>max_concurrent&lt;/code> limit is shedding load. Determine which of the three you are dealing with before touching the Corefile. Editing the Corefile to fix a capacity REFUSED, or scaling replicas to fix a config REFUSED, wastes the incident.&lt;/p></description></item><item><title>CoreDNS returning SERVFAIL: the resolver is failing queries and what to check first</title><link>https://www.netdata.cloud/guides/coredns/coredns-servfail-responses/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-servfail-responses/</guid><description>&lt;p>Applications are failing to resolve names and CoreDNS is answering with SERVFAIL. In Kubernetes this surfaces as connection errors everywhere at once, because nearly all in-cluster communication depends on DNS. SERVFAIL is not one failure. It is CoreDNS saying &amp;ldquo;a plugin in my chain could not answer this query,&amp;rdquo; and the cause is usually upstream DNS, the Kubernetes API, or the Corefile itself.&lt;/p>
&lt;p>Your health checks are probably lying to you. The CoreDNS &lt;code>/health&lt;/code> endpoint on port 8080 only tests process liveness. It does not resolve anything. A pod can return &lt;code>200 OK&lt;/code> to every probe while returning SERVFAIL for every query. The real availability signal is &lt;code>coredns_dns_responses_total{rcode=&amp;quot;SERVFAIL&amp;quot;}&lt;/code> on the metrics endpoint, split by the &lt;code>zone&lt;/code> and &lt;code>plugin&lt;/code> labels.&lt;/p></description></item><item><title>CoreDNS serve_stale: keeping resolution alive while masking upstream failure</title><link>https://www.netdata.cloud/guides/coredns/coredns-serve-stale-masking-failures/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-serve-stale-masking-failures/</guid><description>&lt;p>The &lt;code>serve_stale&lt;/code> option in the CoreDNS cache plugin is a resilience feature with a monitoring side effect that bites teams during real incidents. When it is enabled, CoreDNS answers queries from expired cache entries instead of failing them when the upstream resolver is unreachable. Clients keep resolving names through an upstream outage. Dashboards stay green. The upstream can be dead for an hour before anyone notices, because the one metric that would tell you is almost never graphed.&lt;/p></description></item><item><title>CoreDNS SERVFAIL cache amplification: a one-second blip becomes a five-second outage</title><link>https://www.netdata.cloud/guides/coredns/coredns-servfail-cache-amplification/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-servfail-cache-amplification/</guid><description>&lt;p>Your dashboards show an upstream DNS hiccup that lasted one second. Your users report an outage that lasted five. Both are accurate, and the gap between them is the CoreDNS cache plugin doing what it was designed to do.&lt;/p>
&lt;p>CoreDNS caches SERVFAIL responses for 5 seconds by default. The cache plugin keeps separate positive (&lt;code>success&lt;/code>) and negative (&lt;code>denial&lt;/code>) caches, and SERVFAIL goes into the denial cache alongside NXDOMAIN and NODATA. The intent is sound: RFC 2308 permits caching server-failure responses to shield an already-struggling upstream from a retry storm. The side effect is that a single SERVFAIL answer for a hot record is served to every client that asks during the 5-second window, even after the upstream has fully recovered.&lt;/p></description></item><item><title>CoreDNS serving stale cluster DNS: why you need a functional freshness test</title><link>https://www.netdata.cloud/guides/coredns/coredns-stale-dns-records-freshness-test/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-stale-dns-records-freshness-test/</guid><description>&lt;p>Your CoreDNS dashboards are green. Query rate normal, latency sub-millisecond, SERVFAIL near zero, cache hit ratio healthy. Meanwhile, a Service deleted an hour ago still resolves, and the new Service your team just deployed returns NXDOMAIN. Applications are failing, but nothing in your monitoring fired.&lt;/p>
&lt;p>This is the silent stale data pattern. The kubernetes plugin builds its DNS records from a watch on the API server. If that watch disconnects and cannot re-establish, CoreDNS keeps answering from its in-memory snapshot. The snapshot drifts from reality. No errors go back to clients. No performance metric moves, because the server is genuinely healthy and fast. The data is simply wrong.&lt;/p></description></item><item><title>CoreDNS slow upstream: per-upstream latency, goroutine pileup, and the to label</title><link>https://www.netdata.cloud/guides/coredns/coredns-slow-upstream-latency/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-slow-upstream-latency/</guid><description>&lt;p>Overall DNS latency is climbing. P99 is above 500ms, but P50 looks only mildly elevated. SERVFAIL is nonzero but nowhere near a full outage. The &lt;code>/health&lt;/code> endpoint returns 200, every upstream passes its health checks, and yet clients are complaining that resolution is slow. Meanwhile &lt;code>go_goroutines&lt;/code> is trending up and heap is following it.&lt;/p>
&lt;p>This is the slow upstream drag pattern: one upstream DNS server is responding slowly but still returning valid answers. Because it never actually fails, the forward plugin&amp;rsquo;s health checks never mark it down, so queries keep getting routed to it. Each of those queries holds a goroutine while it waits. Latency accumulates, goroutines accumulate, and memory follows. Left alone, this ends in either &lt;code>max_concurrent&lt;/code> rejects (if you set one) or OOM (if you did not).&lt;/p></description></item><item><title>CoreDNS too many open files: file descriptor exhaustion and refused connections</title><link>https://www.netdata.cloud/guides/coredns/coredns-too-many-open-files/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-too-many-open-files/</guid><description>&lt;p>CoreDNS pods are logging &lt;code>too many open files&lt;/code> and DNS resolution is failing intermittently or completely. Clients see timeouts or refused connections while the process keeps running and &lt;code>/health&lt;/code> still returns 200. Restarting the pod fixes it for a while, then it comes back.&lt;/p>
&lt;p>This is file descriptor exhaustion, and it is a cliff-edge failure. The moment &lt;code>process_open_fds&lt;/code> reaches &lt;code>process_max_fds&lt;/code>, CoreDNS cannot open anything new: no upstream connections, no listening sockets, no log files, no Kubernetes API watch streams. There is no queuing and no graceful degradation. New connection attempts fail immediately and DNS breaks.&lt;/p></description></item><item><title>CoreDNS TTL=0 responses: the anti-pattern that silently bypasses the cache</title><link>https://www.netdata.cloud/guides/coredns/coredns-ttl-zero-defeats-cache/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-ttl-zero-defeats-cache/</guid><description>&lt;p>Your cache hit ratio is sliding. Upstream query volume is climbing. P99 latency is drifting up with it. You open the Corefile and the &lt;code>cache&lt;/code> plugin is right there, configured the way it has been for months. Nothing changed on your side, but the cache has effectively stopped working.&lt;/p>
&lt;p>A common cause is records arriving with TTL=0. When an upstream resolver, or your own zone data, answers with a zero TTL, those answers are uncacheable by contract: every client query for that name has to be forwarded again. The cache plugin is present and correct, but there is nothing for it to hold on to. It looks like a cache failure but is actually a data problem arriving through the response path.&lt;/p></description></item><item><title>CoreDNS UDP buffer errors: kernel receive-buffer overflow dropping queries</title><link>https://www.netdata.cloud/guides/coredns/coredns-udp-buffer-errors-packet-loss/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-udp-buffer-errors-packet-loss/</guid><description>&lt;p>Applications are reporting intermittent DNS timeouts. You open the CoreDNS dashboard and everything looks fine: latency is low, SERVFAIL rate is zero, the health endpoint returns 200, and QPS is suspiciously flat. Not spiking, not zero, just lower than the client demand you know exists.&lt;/p>
&lt;p>This is the UDP buffer cliff. Incoming UDP traffic is exceeding the kernel socket receive buffer on the node, and the kernel is dropping DNS queries before CoreDNS ever reads them. Because CoreDNS only counts the packets it actually receives, every CoreDNS-level metric looks clean. The failure lives one layer below, in the kernel.&lt;/p></description></item><item><title>CoreDNS upstream connection cache misses: new connections adding latency per query</title><link>https://www.netdata.cloud/guides/coredns/coredns-upstream-connection-cache-misses/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-upstream-connection-cache-misses/</guid><description>&lt;p>You are here because forwarded DNS queries got slower, or because &lt;code>coredns_proxy_conn_cache_misses_total&lt;/code> is climbing and you need to know whether it matters. It does. Every connection cache miss means CoreDNS opens a fresh connection to an upstream resolver instead of reusing one from its pool. Setup cost lands on that query, and each new connection holds a file descriptor until it is closed or reaped.&lt;/p>
&lt;p>This is usually degradation, not outage. CoreDNS keeps answering. The damage shows up as worse tail latency on uncached lookups, rising &lt;code>process_open_fds&lt;/code>, and, under sustained churn, resource pressure that can turn into a real incident. Rule of thumb: a miss ratio above 50% sustained for 10 minutes is worth investigating.&lt;/p></description></item><item><title>CoreDNS with NodeLocal DNSCache: what changes about monitoring</title><link>https://www.netdata.cloud/guides/coredns/coredns-nodelocaldns-monitoring/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-nodelocaldns-monitoring/</guid><description>&lt;p>You deployed NodeLocal DNSCache to fix the 5-second timeout race and conntrack pressure, and it worked. DNS latency dropped, the conntrack table stopped filling, and CoreDNS QPS fell off a cliff. Then someone looked at the CoreDNS dashboard, saw near-zero traffic, and concluded CoreDNS was oversized. That conclusion is how the next incident starts.&lt;/p>
&lt;p>NodeLocal DNSCache runs a caching DNS proxy as a DaemonSet on every node. It intercepts pod DNS queries before they enter the iptables DNAT and conntrack path, so each query is answered on the local node instead of traversing NAT to a central CoreDNS pod. This eliminates the kernel race condition behind the 5-second glibc timeout and removes DNS as a conntrack consumer.&lt;/p></description></item><item><title>How CoreDNS actually works in production: the plugin chain mental model</title><link>https://www.netdata.cloud/guides/coredns/coredns-how-it-works-in-production/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/coredns/coredns-how-it-works-in-production/</guid><description>&lt;p>Most CoreDNS incidents are pipeline incidents, not DNS incidents. An upstream resolver gets slow, goroutines pile up, memory climbs, and the pod gets OOMKilled. Or the Kubernetes API watch drops silently and CoreDNS keeps answering every query correctly except the answers are three hours stale. Each failure mode is a direct consequence of how CoreDNS is built internally, and most CoreDNS runbooks assume you already hold that internal model in your head.&lt;/p></description></item></channel></rss>