NAME RESOLUTION  / field guide
Practitioner field guide · 4 September 2026

When name resolution fails, the record was wrong, not the server

Six published incidents between 2021 and 2025, at AWS, Meta, Slack, Cloudflare, Salesforce and Roblox, plus the source trails at Kubernetes, musl and Netflix, reconstruct how production systems actually turn service names into addresses and how that layer fails. After reading you can say, in a design review, which half of your naming system deserves the engineering attention, and why the obvious half is the wrong answer.

28 primary sources 12 production systems 6 incidents Evidence through August 2026 Read: 22 min
01

The territory

Every request your system makes begins by asking a shared, cached, eventually consistent database where to go. This page is about what happens when that database answers wrongly, and who writes the wrong answer.

100%
Availability SLA on Route 53's query-answering data plane, the only such SLA at AWS
62 min
Global loss of a resolver handling ~1.9 trillion queries a day, from one dormant config line
24 h
The TTL on a single parent-zone record that set the clock on Slack's recovery
$25M
Bookings Roblox reported lost to 73 hours of discovery-layer failure

State the problem without naming the technology and it sounds almost too small to study: a service has a name, a client needs an address, something in the middle translates. What makes the translation layer interesting is its shape. It is the only database almost every company runs that is written by one organisation, cached by thousands of others on terms the writer only partially controls, and consulted before any other dependency can even be reached. It sits underneath the monitoring, the deployment tooling and the VPN, which means it sits underneath the things you would use to fix it.

The public record on this layer is unusually good, because when it fails, it fails in front of everyone. This guide is built on six full incident write-ups: Amazon's October 2025 DynamoDB disruption, Meta's October 2021 disappearance, Slack's September 2021 DNSSEC outage, Cloudflare's July 2025 resolver outage, Salesforce's May 2021 multi-instance disruption, and Roblox's 73-hour Consul failure of October 2021, which is the same problem wearing a service-registry costume. Around them sit the build records: Stripe's published resolution path, the Kubernetes NodeLocal DNSCache design, Netflix's decision to bypass DNS entirely for internal traffic in 2012, and the musl libc project's ten-year argument about TCP fallback.

Here is the finding that reorganised this page. Going in, the expectation was a catalogue of overloaded resolvers and unreachable name servers, the read path buckling. That catalogue barely exists. In five of the six incidents the machinery that answers queries stayed healthy; what failed was the machinery that decides what the answers should be. Amazon's automation wrote an empty record. Meta's name servers withdrew themselves, on purpose, exactly as designed. Salesforce pushed a change that its own review process would have caught. Cloudflare attached production prefixes to a non-production topology and a later, unrelated change shipped that state worldwide. Only Slack's incident involved the serving side misbehaving, and even there the trigger was a rollout and the wound was kept open by caches faithfully doing their job. The read path is the most hardened infrastructure on the internet. The write path above it is ordinary software, and it is where this layer actually breaks.

Figure 1 · The two planes of name resolution

Read path

Write path

record writes

Health state,
deploy intent

Planner /
change automation

Enactor(s):
apply via API

Authoritative servers
(anycast, replicated)

Recursive resolvers
(yours and everyone else's)

Stub resolvers
in every client

Read path

Write path

record writes

Health state,
deploy intent

Planner /
change automation

Enactor(s):
apply via API

Authoritative servers
(anycast, replicated)

Recursive resolvers
(yours and everyone else's)

Stub resolvers
in every client

Five of the six incidents in this guide originate in the write-path boxes at the top; the heavily replicated serving chain below mostly did its job. Reconstructed from AWS's postmortem and AWS's own control/data-plane guidance.
Diagram source

The second finding follows from the first and is the one to carry into capacity planning: this layer heals at the speed of its caches, not at the speed of your fix. Slack's engineers rolled back within minutes; the 24-hour TTL on the DS record at the .com zone, and resolvers legitimately reusing a cached denial, decided how long users suffered. Caching is simultaneously the layer's great defence, since Moura et al. measured in 2018 that full resolver caches let about half of clients ride out an authoritative outage, and the reason a bad record outlives its correction. You cannot have one property without the other, and the decisions section below treats TTL as exactly that trade.

Scope. This guide covers internal and external service naming for systems that run on infrastructure they at least partly control: the resolution path, the record-writing control plane, TTL and negative-caching behaviour, and the DNS-versus-registry decision. It deliberately does not cover DNS security as a field (DNSSEC appears only through Slack's operational experience), DDoS defence of authoritative fleets, domain registration and registrar risk, or multicast/zero-conf discovery.

02

How it is actually built

The resolution path that recurs across every published system, and the two components that vary: where the caches sit, and what writes the records.

Strip the branding from Stripe's, Kubernetes' and AWS's published paths and the same five-layer shape appears in all of them. A stub resolver inside the client process asks a cache on the same host; that cache forwards misses to a shared recursive fleet; the fleet asks the authoritative service; and, standing apart from all of it, a control plane computes what the authoritative service should be saying and writes it there through an API. Every layer exists for a measured reason, and each one is attributable.

Figure 2 · Reference resolution path, with the registry variant

Record control plane

Every application host

misses only, TCP upstream

writes

replaces the DNS path
for internal calls

Application

Stub resolver + search path
(glibc / musl, ndots)

Local caching resolver
(Unbound / NodeLocal cache)

Shared recursive fleet
(per-domain forwarding rules)

Authoritative data plane
(anycast, serves records)

Health monitors,
deploy tooling

Planner: computes
desired record set

Enactors: apply
plans via API

Registry variant: Eureka / Consul
heartbeats in, client-cached registry out

Record control plane

Every application host

misses only, TCP upstream

writes

replaces the DNS path
for internal calls

Application

Stub resolver + search path
(glibc / musl, ndots)

Local caching resolver
(Unbound / NodeLocal cache)

Shared recursive fleet
(per-domain forwarding rules)

Authoritative data plane
(anycast, serves records)

Health monitors,
deploy tooling

Planner: computes
desired record set

Enactors: apply
plans via API

Registry variant: Eureka / Consul
heartbeats in, client-cached registry out

The read path is layered caches; the write path is ordinary automation with privileged access to the layer everything trusts. Reconstructed from Stripe's account, KEP-1024 and AWS's postmortem; registry variant from Netflix's Eureka documentation.
Diagram source

Stub resolver and search path

The half of the system nobody budgets for. The stub lives inside your binary, chosen by your base image, and its behaviour is load-bearing: Kubernetes ships ndots:5, so a pod looking up an external name tries the cluster search domains first, multiplying queries, as Marco Pracucci measured in 2019. Alpine images inherited musl's UDP-only resolver until May 2023, so any answer over 512 bytes simply failed.

Documented at: Pracucci, musl 1.2.4 notes

Per-host caching resolver

Stripe runs Unbound on every host; Kubernetes' KEP-1024 added a per-node cache after years of the 5-second-delay issue. The stated reasons are identical: keep queries off the network, and dodge the kernel's conntrack races by answering locally and using TCP upstream. This box exists because of a kernel bug class, not for hit rate.

Runs this way at: Stripe, Kubernetes

Shared recursive fleet

A cluster of resolvers holding the forwarding policy: which domains go to the cloud provider's resolver, which to internal zones, which to the public internet. Stripe's version keeps separate retry-timeout state per forwarding rule so one slow upstream cannot poison timeout calculations for the rest. This is where resolution policy is administered, and where it is observable.

Runs this way at: Stripe

Authoritative data plane

Anycast fleets serving records, engineered to a different standard from everything else on this page: AWS sells Route 53's query answering with a 100% availability SLA, and AWS's Well-Architected guidance describes it as statically stable, able to keep answering with last-known state while its control plane is down. The evidence of the six incidents says this engineering largely works.

Documented at: AWS SLA, REL11-BP04

The record control plane

The planner-and-enactor pair from Amazon's postmortem is the general shape: something watches health and intent, computes the desired record set, and applies it through an API. It is deliberately redundant, which is exactly what made it dangerous: two enactors with no ordering between them is a distributed system, whether or not it was designed as one.

Documented at: AWS, 2025, Salesforce, 2021

The registry variant

Netflix's Eureka and Roblox's Consul replace the DNS path for internal calls with a registry: instances heartbeat in (every 30 seconds at Netflix, eviction after about 90), clients cache the whole registry and keep working from that cache if the registry dies. Fresher health data, bought by operating one more tier-0 stateful system. Section 3 takes the choice apart.

Runs this way at: Netflix, Roblox

Two reconstructions worth flagging as mine rather than reported. First, no published account fully describes the write path's concurrency control; Amazon's postmortem is the closest, and what it describes is enactors checking plan freshness at start and then applying without a fence, which is a read-check-write race textbook. Second, the per-host cache layer is described by Stripe and Kubernetes but only implied elsewhere; treat "every host caches" as corroborated for container platforms and inferred for everything else.

03

The decisions that matter

Four forks in the road, each with the recorded argument and the condition that flips the answer. The fourth one, almost nobody makes deliberately.

Do internal services find each other through DNS, or through a registry?

Chosen: registry
  • Netflix built Eureka in 2012 because, in its words, DNS-style balancing can route traffic "to servers which may not be healthy or may not even exist" in a cloud where instances churn constantly.
  • The clinching property is the client-side cache: Eureka clients keep the full registry locally and survive a registry outage on stale data.
Rejected: plain DNS
  • Eviction speed. DNS learns an instance is gone when the record is rewritten and every cache expires; Eureka's heartbeat model evicts in about 90 seconds without a TTL in the path.
  • Kubernetes went the other way and made DNS the universal interface, then spent KEP-1024 and years of issue threads paying the operational bill.
Flips when
  • You cannot staff the registry as a tier-0 system. Roblox's 73 hours is the price of the registry becoming the platform's most critical database without being operated like one: one cluster, every workload, monitoring that depended on the thing it monitored.

Short TTLs for agility, or long TTLs for survival?

Chosen: short, health-checked
  • Operators of failover-sensitive endpoints run 60-second-class TTLs and let health-checked authoritative servers move traffic; AWS's guidance is to fail over this way, through the data plane, precisely because it keeps record rewrites out of the emergency path.
  • Jung et al. measured back in 2001 that cutting A-record TTLs to a few hundred seconds barely hurts cache hit rates, so the latency cost of short TTLs is small.
Rejected: long everywhere
  • Moura et al. (IMC 2019) showed the other side: raising one ccTLD's TTLs cut median client latency from 183 ms to 28.7 ms, and their 2018 study found full caches let about half of clients ride out an authoritative outage entirely.
  • Long TTLs also mean a bad record, once published, is bad for the full TTL on every cache that picked it up.
Flips when
  • The record is high in the tree or rarely changes: parent-zone records, NS sets, DNSSEC material. There, long TTLs are pure survivability. Slack's 24-hour DS TTL is the cautionary inverse: long TTLs make mistakes durable too, so the flip condition is really "long where correctness is boring, short where contents change".

When the authority is unreachable, serve stale answers or fail closed?

Chosen: serve stale
  • RFC 8767 (2020) standardises answering with expired records when refresh fails, capped at seven days; the RFC records that Akamai had run the mechanism in production since 2011 and that it "smoothed over transient failures and longer outages that would have resulted in major incidents".
  • Demand reached cluster DNS through the front door: CoreDNS issue #4309 asked for it by RFC number, and the cache plugin gained serve_stale.
Rejected: strict expiry
  • The purist reading of TTL as a hard contract. The operational record shows operators chose availability: BIND, Unbound and Knot all ship the option.
Flips when
  • Staleness is the failure. A record moved because the old address is wrong (a failover, a revoked endpoint) is one serve-stale will happily preserve. Serve stale on outage signals only, never as a general TTL extension, and keep it off for records whose whole job is to change.

Fix resolution pathologies in the client library, or in the infrastructure?

Chosen: infrastructure
  • Kubernetes could not fix glibc, musl or the kernel race, so KEP-1024 put a cache on every node, skipped conntrack via NOTRACK, and upgraded upstream queries to TCP: an infrastructure bandage over a client-side wound, and it worked.
Rejected: wait for libc
  • musl's maintainer held for a decade that UDP-only was correct, arguing truncated answers were acceptable and cheaper. The 1.2.4 release notes (May 2023) concede the reversal, "fixing the longstanding inability to query large DNS records". Ecosystems that waited (every Alpine-based image) carried the failure mode for years.
Flips when
  • You own the client. gRPC's naming design makes the resolver a plugin precisely so deployments can swap DNS out per-channel; if you control the binary, fixing resolution behaviour there is cheaper than running a caching daemon on every node forever.

Figure 3 · Choosing who answers the name

external clients,
browsers, partners

your own services

minutes are fine;
LB owns health

seconds; per-instance
state matters

yes, with independent
monitoring

no

Who consumes
the name?

Public DNS, health-checked records,
failover via data plane only

Instance churn and
health granularity needed?

Internal DNS zones,
short TTLs, local caches

Will you operate a
registry as tier-0?

Registry with client-side cache
(Eureka / Consul model)

Stay on DNS,
accept slower eviction

external clients,
browsers, partners

your own services

minutes are fine;
LB owns health

seconds; per-instance
state matters

yes, with independent
monitoring

no

Who consumes
the name?

Public DNS, health-checked records,
failover via data plane only

Instance churn and
health granularity needed?

Internal DNS zones,
short TTLs, local caches

Will you operate a
registry as tier-0?

Registry with client-side cache
(Eureka / Consul model)

Stay on DNS,
accept slower eviction

Terminal boxes are commitments, not preferences: the registry branch is a commitment to operate it as tier-0, which is the clause Roblox's incident tested. Derived from the decisions above.
Diagram source
DecisionChosenRejectedBecauseEvidence
Internal discoveryRegistry (Netflix), DNS (Kubernetes)The other oneEviction speed vs. one more tier-0 systemEureka docs, KEP-1024
TTL policyShort + health checks at leavesLong everywhereFailover speed; hit-rate cost is small (2001)Jung et al., Moura 2019
Expiry under outageServe stale, 7-day capStrict expiryAkamai ran it since 2011; availability wonRFC 8767, CoreDNS #4309
Where to fix clientsNode-level cache + TCPWait for libcCould not ship a glibc/musl/kernel fixk8s #56903, musl thread
Failover mechanismHealth checks (data plane)Emergency record editsControl plane is exactly what fails under stressAWS REL11-BP04

One decision the record shows almost nobody making deliberately: how the record-writing automation serialises its writers. Amazon's postmortem describes redundant enactors racing; Salesforce's describes an emergency change lane that skipped review; Cloudflare's describes a config store where a dormant error waited for an unrelated change to ship it globally. Three different companies, one missing decision: what orders and gates writes to the layer everything trusts. If your zone automation has two writers and no fencing, you have made Amazon's choice without Amazon's postmortem.

04

What broke in production

Six incidents, three failure classes. The class names are mine; the incidents keep sorting themselves into them.

Reading the six write-ups together, each incident lands in one of three classes. Class one: the writer corrupts the record. The serving fleet is healthy and faithfully serves a wrong answer that automation or a change process wrote (AWS, Salesforce, Cloudflare). Class two: the system depends on itself. The failure disables the tools needed to repair it, because naming sits under the tooling (Meta, Roblox). Class three: the cache preserves the wound. The fix ships fast and the installed base of caches keeps serving the failure (Slack, and the long tail of the AWS recovery). Class one is where prevention pays; class two is where recovery planning pays; class three is where you mostly pay in advance, by choosing TTLs.

Figure 4 · The race that emptied dynamodb.us-east-1.amazonaws.com

Regional endpointrecordEnactor BEnactor A (delayed)DNS PlannerRegional endpointrecordEnactor BEnactor A (delayed)DNS Plannerstalls, holding plan100record now empty.Automation wedged,repair is manualplan 100plans 101 ... 140apply plan 140 (current)apply plan 100 (stale overwrite)cleanup deletes plansolder than 140delete plan 100 and its records
Regional endpointrecordEnactor BEnactor A (delayed)DNS PlannerRegional endpointrecordEnactor BEnactor A (delayed)DNS Plannerstalls, holding plan100record now empty.Automation wedged,repair is manualplan 100plans 101 ... 140apply plan 140 (current)apply plan 100 (stale overwrite)cleanup deletes plansolder than 140delete plan 100 and its records
A delayed writer's stale plan overwrote a newer one, then garbage collection deleted the plan whose records were live. Plan numbers are illustrative; the sequence follows AWS's October 2025 postmortem.
Diagram source
Class 1 · writer corrupts record

AWS: two enactors, no fence, empty record

AssumptionRedundant DNS Enactors applying planner output could not interleave destructively; plan-freshness checks at start were enough.
What happenedOne enactor ran "unusually high delays", applied a stale plan over a newer one; the other's cleanup then deleted that plan as stale, "immediately removing all IP addresses for the regional endpoint" and leaving a state no enactor could repair.
Blast radiusDynamoDB endpoint resolution gone in us-east-1 from 11:48 PM PDT Oct 19, 2025; record manually repaired by ~2:40 AM; dependent services (EC2 launches, Lambda, and everything atop them) recovered through 2:20 PM.
FixAutomation "disabled worldwide" pending safeguards against the race; velocity controls added downstream.
Design ruleA redundant record-writer is a distributed system: writes need monotonic versions and a fence, and delete is a write. If cleanup can delete what serving depends on, staleness checks at start are theatre.
Class 1 · writer corrupts record

Salesforce: the emergency lane ships a DNS change

AssumptionA DNS configuration script "deployed without ill effects over three years" was safe to push globally through the emergency process.
What happenedThe script misbehaved during a zone transfer; name servers did not restart as expected; the RCA's sharpest finding is process subversion: "there was no active or imminent Severity-0, Severity-1 or Severity-2 incident, so the EBF process should not have been used".
Blast radiusMulti-instance disruption across Salesforce properties, roughly four hours, May 11-12, 2021; the status site was affected too.
FixEmergency-change criteria tightened; staggered rollout for DNS changes.
Design ruleThe change process is part of the naming architecture. A global blast radius with a bypassable review gate will eventually be exercised by a tired engineer, so make the safe path the fast path for DNS specifically.
Class 1 · writer corrupts record

Cloudflare: a dormant config error ships globally

AssumptionA config error that produced no symptom was no threat; topology bindings for 1.1.1.1's prefixes were correct because nothing had broken.
What happenedA June change linked resolver prefixes to a non-production topology and "remained dormant" until July 14, 2025, when an unrelated change triggered a global config refresh; production data centres withdrew the 1.1.1.1 prefixes everywhere at once.
Blast radius62 minutes, 21:52 to 22:54 UTC, for a resolver handling roughly 1.9 trillion queries a day; every client with 1.1.1.1 as sole resolver lost resolution entirely.
FixStaged rollout for such config, and deprecation of the legacy system that allowed the binding.
Design ruleLatent config is live config waiting for a trigger. Validate the whole desired state on every global refresh, not just the delta; and clients should configure two resolver providers, not two addresses of one.
Class 2 · self-dependency

Meta: the name servers withdrew themselves, as designed

AssumptionDNS servers withdrawing their BGP routes when they cannot reach the data centres is a health feature; the whole backbone would never be unreachable at once.
What happenedAn audit command "unintentionally took down all the connections in our backbone network" after "a bug in that audit tool prevented it from properly stopping the command"; every DNS server then executed its design: "our DNS servers disable those BGP advertisements if they themselves can not speak to our data centers". Facebook vanished from the routing table.
Blast radiusRoughly six hours, October 4, 2021, all Meta properties; internal tools and badge systems on the same infrastructure, so engineers needed physical access to routers "designed to be difficult to modify even when you have physical access".
FixOut-of-band access hardened; the withdrawal behaviour reviewed against total-disconnection scenarios.
Design ruleAny health-triggered self-removal needs a floor: "if this check would remove every serving node, the check is wrong". And the credentials, consoles and doors you will use to repair naming must not resolve through it.
SourceMeta postmortem, Oct 2021, external view: Kentik
Class 2 · self-dependency

Roblox: the discovery layer was also under the monitoring

AssumptionOne Consul cluster could serve discovery, health, KV and leader election for every workload, and the telemetry watching Consul could itself depend on Consul.
What happenedA new streaming feature "under unusually high read and write load led to excessive contention", compounded by a pathological BoltDB performance issue; with discovery down, everything was down, and the circular dependency between telemetry and Consul left responders diagnosing blind.
Blast radius73 hours, October 28-31, 2021, 50 million daily users; about $25M in bookings by the company's own estimate.
FixConsul isolated per workload, telemetry decoupled from Consul, extra data centre for redundancy.
Design ruleWhatever answers "where is X" is your most critical database; shard it by consumer, and never let its own observability resolve through it. This is Meta's rule wearing registry clothes.
Class 3 · cache preserves the wound

Slack: rollback in minutes, recovery in a day

AssumptionIf the DNSSEC rollout went wrong, pulling the DS record would restore the previous world quickly. Two earlier aborted attempts had reinforced the sense that rollback worked.
What happenedOn the third attempt (September 30, 2021), a Route 53 bug in "the NSEC type bitmap produced ... for wildcard domains" let resolvers cache a denial that slack.com records existed; validating resolvers kept answering NXDOMAIN from that cache after the rollback.
Blast radiusHours of failed resolution for users behind affected validating resolvers; "as public resolver caches were flushed and as the 24-hour TTL on the DS record at the '.com' zone expired, the error rates went back to normal".
FixVendor fixed the NSEC synthesis bug; Slack's talk ("Third Time's the Outage") turned the attempt history into the industry's reference account of DNSSEC operations.
Design ruleBefore any change to naming, compute the rollback horizon: the maximum TTL any cache in the chain may hold on what you are about to publish. If you cannot live with that horizon as your outage duration, do not ship the change that way.
SourceSlack postmortem, 2021, mechanism corroborated by Huston, OARC 36

Figure 5 · The rollback horizon: why the fix is not the recovery

parent-zone records,
e.g. DS: 24h TTL

record TTLs,
60s to 48h

cached denials
linger too

Operator publishes
the correction

Authoritative servers:
new answer immediately

Parent / TLD caches

Public and ISP resolvers,
positive and negative caches

OS and library caches

Client finally
sees recovery

parent-zone records,
e.g. DS: 24h TTL

record TTLs,
60s to 48h

cached denials
linger too

Operator publishes
the correction

Authoritative servers:
new answer immediately

Parent / TLD caches

Public and ISP resolvers,
positive and negative caches

OS and library caches

Client finally
sees recovery

An operator's fix propagates only as fast as each cache layer expires what it holds; the slowest TTL in the chain, 24 hours in Slack's case, is the real recovery time. Assembled from Slack's account and RFC 8767's cache model.
Diagram source

The class-two incidents deserve one more sentence, because they rhyme across a decade of this material: Meta could not reach its tools because the tools resolved through the thing that failed, and Roblox could not see Consul because the telemetry resolved through Consul. No public postmortem in this corpus describes the inverse, a naming failure contained because the repair path was verified independent. Either nobody builds that verification, or nobody who builds it has needed to write a postmortem. Both readings argue for a game day that severs naming and then tries to use your own consoles.

05

Numbers you can plan against

Scale, latency and cost figures from the sources, each dated. The planning paragraph below separates what was measured from what was claimed.

MetricValueAtContextAs ofSource
Public resolver query volume~1.9T/dayCloudflare 1.1.1.1Scale of the thing that vanished for 62 minutesearly 2025ISOC Pulse
Resolver outage duration62 minCloudflareGlobal withdrawal from one config refresh2025-07postmortem
Record-to-repair time~3 hAWS DynamoDBEmpty record 11:48 PM to manual repair ~2:40 AM2025-10postmortem
Dependent-service recovery tail+12 hAWS us-east-1Services atop DynamoDB recovered through 2:20 PM2025-10ThousandEyes
Total outage, self-dependent recovery~6 hMetaPhysical access required to repair remotely-run network2021-10postmortem
Discovery-layer outage73 h / ~$25MRobloxConsul contention + BoltDB pathology; company's own figures2021-10postmortem, DCF
Rollback horizon, parent zone24 hSlack / .comDS-record TTL that bounded DNSSEC un-rollout2021-09postmortem
Latency lever of TTL183 → 28.7 ms.uy ccTLDMedian latency after raising TTL from 5 min to 1 day2019Moura, IMC '19
Cache protection during outage~50% of clientsmeasured testbedRide out an authoritative outage with full caches; retries amplify traffic up to 8×2018Moura, IMC '18
Lookups receiving no answer23%MIT traceFailure traffic dominated DNS packets even in 20012001Jung et al.
Client-side stall, conntrack race5 s (up to 30 s)KubernetesDropped UDP packet waits out resolver timeout; 3 retries × (A + AAAA)2019KEP-1024
Registry eviction clock30 s / ~90 sNetflix EurekaHeartbeat interval / eviction after missed renewalschecked 2026Eureka docs
Serve-stale ceiling7 daysIETFSuggested cap on serving expired records during outage2020RFC 8767
Data-plane availability SLA100%AWS Route 53Query answering only; record changes carry no such SLAchecked 2026SLA
Read these carefully

Measured, from primary sources: the outage durations, the Moura and Jung figures, the KEP timings. Claimed, by the operator: Roblox's $25M, the 1.9T queries/day, and every SLA (an SLA is a refund schedule, not a measurement). Derived, by me: the "+12 h" AWS tail is the gap between the postmortem's repair time and its full-recovery time, corroborated by external monitoring. The 2001 MIT failure rate is a different internet; keep it as an order-of-magnitude reminder that failure traffic dominates, not as a current figure. No public source in this corpus prices the record control plane itself; what a planner/enactor pipeline costs to run safely is an open number.

06

The evidence wall

Every source behind this page, graded. Filter by kind.

Postmortem AWS2025-10

Summary of the Amazon DynamoDB Service Disruption in US-EAST-1

The most detailed public description of a DNS record control plane anywhere: planner, redundant enactors, the race, the empty record, and the admission that the automation was disabled worldwide afterwards.

Carry forwardYour zone automation is a distributed system; version and fence its writes, including deletes.
aws.amazon.com/message/101925
Postmortem Meta2021-10

More details about the October 4 outage

The self-dependency incident: DNS servers designed to withdraw their BGP routes on lost backbone connectivity all did so at once, and the repair tooling resolved through the thing that failed.

Carry forwardHealth-triggered self-removal needs a floor; repair paths must not resolve through what they repair.
engineering.fb.com
Postmortem Slack2021-11

What happened during Slack's DNSSEC rollout

A vendor bug in NSEC synthesis for wildcards let resolvers cache a denial of slack.com's existence; the rollback was fast and irrelevant, because caches held the wound open for up to 24 hours.

Carry forwardCompute the rollback horizon (the slowest TTL in the chain) before shipping any naming change.
slack.engineering
Postmortem Cloudflare2025-07

Cloudflare 1.1.1.1 incident on July 14, 2025

A config error dormant since June was shipped globally by an unrelated change's refresh; 62 minutes without the world's second-largest public resolver.

Carry forwardValidate desired state on every global refresh, not just the delta; latent config is live.
blog.cloudflare.com
Postmortem Salesforce2021-05

Multi-Instance Service Disruption on May 11-12, 2021

A DNS change pushed through the emergency lane without an emergency; servers failed to restart after a zone transfer. Unusually frank about the process failure.

Carry forwardThe change process is part of the naming architecture; close the bypass lane for global-blast changes.
help.salesforce.com
Postmortem Roblox2022-01

Roblox Return to Service 10/28-10/31 2021

The registry version of this failure: one Consul cluster under everything, a streaming feature and a BoltDB pathology, and telemetry that depended on the system it watched. 73 hours.

Carry forwardThe discovery layer is your most critical database; shard it and monitor it from outside itself.
blog.roblox.com
Design doc Kubernetes SIG-Network2019

KEP-1024: NodeLocal DNS Cache

The accepted design that ended the 5-second-delay era: per-node cache, conntrack bypass, TCP upstream. The motivation section is a compressed history of everything wrong with in-cluster DNS.

Carry forwardWhen you cannot fix the client or the kernel, interpose a cache you control on the same host.
github.com/kubernetes/enhancements
RFC IETF2020-03

RFC 8767: Serving Stale Data to Improve DNS Resiliency

Standardises answering with expired records when the authority is unreachable, suggested cap seven days, and records Akamai running it in production since 2011.

Carry forwardServe stale on outage signals; keep it away from records whose job is to change.
datatracker.ietf.org/doc/html/rfc8767
Design doc gRPCmaintained

gRPC Name Resolution (doc/naming.md)

DNS as the default name system, deliberately behind a plugin interface so deployments can substitute xDS or registry resolvers per channel.

Carry forwardIf you own the client, resolution is a swappable policy, not a fact of the platform.
github.com/grpc/grpc/doc/naming.md
Issue thread Kubernetes2017-12

#56903: DNS intermittent delays of 5s

The thread where a platform's worth of users converged on the same symptom and traced it to kernel conntrack races on parallel UDP queries, not to any DNS server.

Carry forwardA resolution SLO must include the client side; the server fleet can be perfect while every lookup stalls 5 s.
github.com/kubernetes/kubernetes/issues/56903
Issue thread CoreDNS2020-11

#4309: Add support for serving stale data according to RFC 8767

Serve-stale demand arriving in cluster DNS by RFC number; the cache plugin gained serve_stale as a result.

Carry forwardResilience features standardised for the public DNS migrate inward; check what your resolver already ships.
github.com/coredns/coredns/issues/4309
Mailing list musl2020-04

Thread: TCP support in the stub resolver

The recorded argument for the rejected approach: truncated UDP answers treated as acceptable, bounded, and cheaper than TCP round trips. Every Alpine image carried the consequence.

Carry forwardA rejected fix in a dependency is a standing production risk you inherit silently; read your libc's position, not just its docs.
openwall.com/lists/musl/2020/04/21/8
Release notes musl2023-05

musl 1.2.4 released: TCP fallback lands

The reversal, in the project's own words: "fixing the longstanding inability to query large DNS records". A decade of ecosystem pain closed in one release.

Carry forwardPin base images with eyes open: resolver behaviour is part of the image contract.
openwall.com/lists/musl/2023/05/02/1
Docs-as-source Netflixchecked 2026

Eureka at a glance

Netflix's own statement of why internal traffic bypasses DNS: registry with 30-second heartbeats, ~90-second eviction, and clients that survive registry outages on cached state.

Carry forwardThe client-side registry cache is the load-bearing feature; a registry without it is just slower DNS.
github.com/Netflix/eureka/wiki
Paper MIT (Jung, Sit, Balakrishnan, Morris)2001

DNS Performance and the Effectiveness of Caching

The foundational measurement: cutting A-record TTLs to a few hundred seconds barely hurts hit rates, NS-record caching is what protects the system, and 23% of traced lookups got no answer at all.

Carry forwardShort leaf TTLs are cheap; long TTLs high in the tree are what actually shield you.
conferences.sigcomm.org (PDF)
Paper Moura, Heidemann, Hardaker, Schmidt2019

Cache Me If You Can: Effects of DNS Time-to-Live (IMC '19)

TTL as a latency lever, measured: one ccTLD's raise from five minutes to a day cut median latency from 183 ms to 28.7 ms, and the operator changed production after seeing the data.

Carry forwardAudit inherited TTLs; someone chose them years ago for reasons that no longer apply.
dl.acm.org/10.1145/3355369.3355568
Paper Moura et al.2018

When the Dike Breaks: Dissecting DNS Defenses During DDoS (IMC '18)

Caching quantified as the DNS's principal outage defence: full caches carry about half of clients through an authoritative outage, while client retries multiply load on the struggling authority up to 8×.

Carry forwardCache warmth is an availability asset; measure your resolvers' hit rates as reliability, not just performance.
dl.acm.org/10.1145/3278532.3278534
Talk Slack at USENIX SREcon22 EMEA2022-10

Slack's DNSSEC Rollout: Third Time's the Outage

The conference version of the postmortem, with the attempt-by-attempt history the blog compresses; the title alone records that two aborted rollouts preceded the incident. Slides linked from the session page.

Carry forwardAborted attempts are evidence about your rollback story; two clean aborts do not prove the third will roll back.
usenix.org/conference/srecon22emea
Talk Moura at RIPE 772018-10

When the Dike Breaks (operator presentation)

The IMC '18 findings presented to the operator community that runs the resolvers in question; the slide deck is the fastest way into the caching-as-defence data.

Carry forwardThe measured defence of the whole system is caches you do not operate; design assuming both their help and their memory.
ripe77.ripe.net (slides PDF)
Eng blog Stripe2019

The secret life of DNS packets: investigating complex networks

The clearest published internal resolution path: Unbound on every host and as a shared fleet, per-domain forwarding rules, per-rule timeout state, and the metrics pipeline watching it all.

Carry forwardIsolate timeout and retry state per upstream rule, or one slow forwarder poisons the rest.
stripe.com/blog/secret-life-of-dns
Eng blog Martynas Pumputis2018-08

Racy conntrack and DNS lookup timeouts

The kernel-level diagnosis behind the 5-second delays, written by the engineer who then fixed part of it upstream: parallel A and AAAA queries over one socket race in conntrack insertion and one packet is silently dropped.

Carry forwardUDP through NAT is where resolution goes to be flaky; prefer TCP or NOTRACK on the DNS path.
lambda.lt/blog/2018/racy_conntrack
Eng blog Marco Pracucci2019

Kubernetes pods, /etc/resolv.conf ndots:5, and application performance

The measurement that made ndots:5 famous: every external lookup from a default pod walks the search domains first, multiplying queries and latency.

Carry forwardUse FQDNs with trailing dots or per-pod dnsConfig; defaults chosen for cluster names tax every external call.
pracucci.com
Analysis Geoff Huston / APNIC2021-12

ISP Column: notes from DNS-OARC 36

Independent expert corroboration of the Slack mechanism: the NSEC type-bitmap error and why aggressively-caching validating resolvers kept denying slack.com after the rollback.

Carry forwardNegative answers are cached too; a bug that synthesises denials is worse than one that drops queries.
potaroo.net/ispcol/2021-12/oarc36
Analysis Kentik2021-10

Facebook's historic outage, explained

The outside view of Meta's incident: global BGP monitoring watched the nameserver prefixes withdraw minutes before resolution failed worldwide.

Carry forwardExternal synthetic resolution checks see what your internal monitoring, inside the blast radius, cannot.
kentik.com/blog
Analysis Internet Society2025-07

Lessons from the Cloudflare 1.1.1.1 outage: a resilience perspective

Puts the 62 minutes in ecosystem terms: ~1.9 trillion queries a day, and the plain warning that one upstream resolver, however good, is a single point of failure.

Carry forwardConfigure resolver diversity across providers, not just across addresses of one provider.
pulse.internetsociety.org
Vendor AWSchecked 2026

Amazon Route 53 Service Level Agreement

The 100% availability SLA on query answering, and, by its silence, the absence of any equivalent commitment on record changes. The asymmetry is the thesis of this page in contract form.

Carry forwardRead what the SLA covers; the write path of your naming layer carries no availability promise anywhere in the industry.
aws.amazon.com/route53/sla
Vendor AWS Well-Architected2025-02

REL11-BP04: Rely on the data plane and not the control plane during recovery

AWS's own doctrine: Route 53's control plane lives in us-east-1, its data plane in 200+ PoPs, and failover should ride health checks, never emergency record edits. Published months before the October 2025 incident tested the write path.

Carry forwardAnything you must do during an incident should require zero record writes.
docs.aws.amazon.com
Vendor ThousandEyes2025-10

AWS Outage Analysis: October 20, 2025

Independent external timeline of the DynamoDB incident, corroborating the repair time and the long dependent-service tail after the record was fixed.

Carry forwardFixing the record is the start of recovery, not the end; budget for the dependency tail.
thousandeyes.com/blog
07

Build a miniature, then productionise it

Six rungs from an evening's toy to a production-shaped drill. The line from reading to skill is crossed at rung four, where you reproduce Amazon's race on your laptop.

Run the read path yourself

Stand up Unbound or CoreDNS as a recursive resolver, point dig through it, and watch the same query answered by the authority, then by the cache. Lower a record's TTL at a zone you control and watch the change propagate.

Done when: you can show, with timestamps, a cached answer surviving after the authoritative record changed.  Teaches: the cache hierarchy is the system; the authority is just its source of truth.

Break the authority, then serve stale

Firewall your resolver off from the authority mid-run. Watch answers keep flowing until TTL expiry, then fail. Enable serve-expired (Unbound) or serve_stale (CoreDNS) and repeat.

Done when: the same outage produces SERVFAIL in one config and stale answers in the other, and you can say which your production resolvers do today.  Teaches: RFC 8767's trade, felt rather than read.

Reproduce the client-side tax

In a default Kubernetes pod, tcpdump port 53 while resolving an external name. Count the search-domain expansions from ndots:5 and the parallel A/AAAA pairs. Then add a trailing dot and count again.

Done when: you have the two packet counts side by side.  Teaches: half the resolution system ships inside your base image, configured by someone else.

Build a planner/enactor, then race it

Write a planner emitting numbered zone plans and two enactors applying them to a local zone file or test zone, with a cleanup step that deletes old plans. Add a random stall to one enactor. When the empty-record state appears, fix it properly: monotonic plan numbers checked at apply time, and cleanup that refuses to delete the active plan.

Done when: the stale writer's apply is rejected by version check, under a stress loop, every time.  Teaches: the write path is a distributed system, and Amazon's October 2025 failure mode fits in 200 lines.

Race DNS against a registry

Run a toy registry (heartbeat in, JSON out, client cache) next to a DNS zone with 60-second TTLs, both fronting the same two backends. Kill a backend and measure time-to-eviction on each path; then kill the registry and watch clients coast on cached state.

Done when: you have both eviction curves on one chart and can defend a choice between them for your own workload.  Teaches: the freshness-versus-operability trade that separates Netflix's choice from Kubernetes'.

Run the severance game day

In staging, make internal DNS lie: empty answers for one service, NXDOMAIN for another, five-second delays for a third. Watch which clients retry, which cache the failure, which crash. Then the class-two drill: with resolution down, try to reach your own dashboards, runbooks and cloud consoles.

Done when: you have a written inventory of what breaks, and at least one repair tool verified to work with naming down.  Teaches: Meta's and Roblox's lesson at staging prices; failure here is not binary, and the repair path is part of the architecture.

08

Keep hunting

The queries that found the material above, so the reader can extend the search when this page goes stale.

Postmortems and incident detail

  • "DNS Enactor" "DNS Planner" race condition
  • site:engineering.fb.com outage BGP DNS "disable those BGP advertisements"
  • "what happened during" DNSSEC rollout NXDOMAIN negative caching
  • "multi-instance service disruption" DNS "emergency break fix"
  • "return to service" Consul BoltDB contention postmortem

The client side and the kernel

  • kubernetes "DNS intermittent delays of 5s" conntrack insert_failed
  • "racy conntrack and dns lookup timeouts"
  • "ndots:5" resolv.conf performance kubernetes
  • musl "tcp fallback" DNS truncated 512 bytes

Mechanism, standards, measurement

  • "serve stale" RFC 8767 resolver production Akamai
  • "cache me if you can" DNS TTL IMC
  • "when the dike breaks" DNS caching DDoS
  • "effectiveness of caching" DNS trace TTL

Decisions and alternatives

  • eureka wiki "may not be healthy or may not even exist"
  • grpc naming.md resolver plugin dns
  • "NodeLocal" dnscache KEP conntrack NOTRACK motivation
  • "data plane" "control plane" route 53 static stability failover

The pattern behind the queries: exact phrases learned from one source ("DNS Enactor", "insert_failed", "serve stale") retrieve the layer of material the generic query never surfaces. Search the vocabulary a system taught you, not the name of the technology.

09

References

  1. AWS, Summary of the Amazon DynamoDB Service Disruption in the Northern Virginia (US-EAST-1) Region aws.amazon.com, October 2025. Checked 2026-09-04.
  2. Meta, More details about the October 4 outage engineering.fb.com, 2021-10-05. Checked 2026-09-04.
  3. Slack, What happened during Slack's DNSSEC rollout slack.engineering, November 2021. Checked 2026-09-04.
  4. Cloudflare, Cloudflare 1.1.1.1 incident on July 14, 2025 blog.cloudflare.com, July 2025. Checked 2026-09-04.
  5. Salesforce, Multi-Instance Service Disruption on May 11-12, 2021 help.salesforce.com, May 2021. Checked 2026-09-04.
  6. Roblox, Roblox Return to Service 10/28-10/31 2021 blog.roblox.com, January 2022. Checked 2026-09-04.
  7. Kubernetes SIG-Network, KEP-1024: NodeLocal DNS Cache github.com/kubernetes/enhancements, 2019. Checked 2026-09-04 (fetched directly).
  8. Lawrence, Kumari, Sood, RFC 8767: Serving Stale Data to Improve DNS Resiliency IETF, March 2020. Checked 2026-09-04.
  9. gRPC, Name Resolution (doc/naming.md) github.com/grpc/grpc, maintained. Checked 2026-09-04 (fetched directly).
  10. Kubernetes issue #56903, DNS intermittent delays of 5s github.com, December 2017. Checked 2026-09-04.
  11. Weaveworks issue #3287, DNS lookup timeouts due to races in conntrack github.com, 2018. Checked 2026-09-04.
  12. CoreDNS issue #4309, Add support for serving stale data according to RFC 8767 github.com, November 2020. Checked 2026-09-04.
  13. musl, 1.2.4 release announcement openwall.com lists, 2023-05-02. Checked 2026-09-04.
  14. musl mailing list, Re: TCP support in the stub resolver openwall.com lists, 2020-04-21. Checked 2026-09-04.
  15. musl commit, dns: implement tcp fallback in __res_msend query core git.musl-libc.org, April 2023. Checked 2026-09-04.
  16. Netflix, Eureka at a glance github.com/Netflix/eureka wiki, maintained. Checked 2026-09-04 (fetched directly).
  17. Netflix, Netflix Shares Cloud Load Balancing And Failover Tool: Eureka! Netflix Tech Blog, September 2012. Checked 2026-09-04.
  18. Jeff Jo, The secret life of DNS packets: investigating complex networks Stripe engineering blog, 2019. Checked 2026-09-04.
  19. Martynas Pumputis, Racy conntrack and DNS lookup timeouts lambda.lt, 2018-08-16. Checked 2026-09-04.
  20. Marco Pracucci, Kubernetes pods /etc/resolv.conf ndots:5 option and why it may negatively affect your application performances pracucci.com, 2019. Checked 2026-09-04.
  21. Geoff Huston, ISP Column: DNS-OARC 36 potaroo.net, December 2021. Checked 2026-09-04.
  22. Kentik, Facebook's historic outage, explained kentik.com, October 2021. Checked 2026-09-04.
  23. Internet Society, Lessons from the Cloudflare 1.1.1.1 Outage: A Resilience Perspective pulse.internetsociety.org, July 2025. Checked 2026-09-04.
  24. Jung, Sit, Balakrishnan, Morris, DNS Performance and the Effectiveness of Caching ACM SIGCOMM IMW, 2001. Checked 2026-09-04.
  25. Moura, Heidemann, Hardaker, Schmidt, Cache Me If You Can: Effects of DNS Time-to-Live ACM IMC, October 2019. Checked 2026-09-04.
  26. Moura et al., When the Dike Breaks: Dissecting DNS Defenses During DDoS ACM IMC, October 2018. Checked 2026-09-04.
  27. Slack, Slack's DNSSEC Rollout: Third Time's the Outage USENIX SREcon22 EMEA, October 2022. Slides: PDF. Checked 2026-09-04.
  28. Moura, When the Dike Breaks (presentation) RIPE 77, October 2018. Checked 2026-09-04.
  29. AWS, Amazon Route 53 Service Level Agreement aws.amazon.com, current version. Checked 2026-09-04.
  30. AWS Well-Architected, REL11-BP04: Rely on the data plane and not the control plane during recovery docs.aws.amazon.com, February 2025. Checked 2026-09-04.
  31. ThousandEyes, AWS Outage Analysis: October 20, 2025 thousandeyes.com, October 2025. Checked 2026-09-04.
  32. Data Center Frontier, Metaverse Platform Roblox Adds Data Center to Address 73-Hour Outage datacenterfrontier.com, 2022. Checked 2026-09-04.

Access note: this guide was researched from an environment whose sandbox could fetch GitHub-hosted sources directly; all other pages were located, date-confirmed and quote-verified through search-engine retrieval of the cited URL on the date shown. Quotes are reproduced only where the cited page's own text was returned verbatim.