L7 · management · reviewed
DNS
Domain Name System
A delegated, cached database that answers questions about names — and whose two most useful signals are the record type asked for and how long the answer may be remembered.
Presenter modeEmbed this figure
Why it exists
Early ARPANET hosts kept a file called HOSTS.TXT listing every machine on the network. One organisation edited it, everyone downloaded it, and the arrangement failed on all three axes at once: the file grew, the edits centralised, and any change took as long as the slowest download.
DNS replaces it with a tree whose branches are handed out. The owner of example.com answers for everything beneath it without asking anyone, and the only thing the level above has to store is where to send the question. Nothing has to know the whole namespace, so the namespace can be any size. The history of domain namesRFC 1034 · INTERNET STANDARD · November 1987
Caching is the other half, and it is what makes the delegation affordable. Every answer carries a TTL saying how long it may be reused, so the root servers are consulted once per resolver per cache lifetime rather than once per lookup. Using the cacheRFC 1035 · INTERNET STANDARD · November 1987
Both halves have a cost. Delegation means the answer you get depends on which server you asked, and caching means it depends on when you asked. Most DNS troubleshooting is establishing which of those two is responsible for the answer in front of you.
One name, four questions
A resolver with an empty cache walks down from the root. Each server it asks answers with a referral rather than an answer, until one is authoritative.
The laptop asks for the A record of www.example.com and sets one bit: Recursion Desired. That bit is the whole of its participation — it will do no work beyond waiting. Laptop · stub resolver. Recursive resolver: Cache empty. Root · a.root-servers.net. .com · a.gtld-servers.net. example.com · ns1.
- Link
- Blocking
- Packet in flight
- Discarded
- Emphasis
Text equivalent of this diagram
| Element | Kind | State |
|---|---|---|
| Laptop · stub resolver | host | — |
| Recursive resolver | router | Cache: empty |
| Root · a.root-servers.net | cloud | — |
| .com · a.gtld-servers.net | cloud | — |
| example.com · ns1 | cloud | — |
| Laptop · stub resolver — Recursive resolver | link | up · RD=1 |
| Recursive resolver — Root · a.root-servers.net | link | up · query |
| Recursive resolver — .com · a.gtld-servers.net | link | up · query |
| Recursive resolver — example.com · ns1 | link | up · query |
The laptop asks for the A record of www.example.com and sets one bit: Recursion Desired. That bit is the whole of its participation — it will do no work beyond waiting.
A stub resolver is deliberately incapable. It cannot follow a referral, so it depends entirely on a server willing to do that on its behalf — which is why RA coming back clear is fatal rather than merely disappointing.
What changed
- A? www.example.com · RD=1: Laptop · stub resolver → Recursive resolver
- Recursive resolver: Cache → empty
How it works
A query names three things: the name, the class (always IN in practice), and the type. The type matters more than people expect — asking for A and asking for MX are different questions about the same name, and one can exist while the other does not. TYPE valuesRFC 1035 · INTERNET STANDARD · November 1987
A reply has four sections, counted in the header. The answer section holds records matching the question; the authority section holds either a referral or the SOA that bounds a denial; the additional section holds glue addresses and the OPT pseudo-record. Reading the counts is how you tell a referral from an answer from a denial. Header section formatRFC 1035 · INTERNET STANDARD · November 1987
A recursive resolver starts at the root and follows referrals down until a server answers with the AA bit set. It caches every step, so the next lookup in the same zone starts much further down the tree. AlgorithmRFC 1034 · INTERNET STANDARD · November 1987
Records of the same name, class and type form an RRset, and an RRset is indivisible: it is served whole, cached whole, expires whole and — under DNSSEC — signed whole. All records in it share one TTL, so configuring different values for two A records of the same name is not a thing the protocol can express. TTLs of RRs in an RRSetRFC 2181 · PROPOSED STANDARD · July 1997
Queries go over UDP first and over TCP when the reply will not fit. EDNS(0) lets the requestor advertise a buffer larger than the original 512 octets, and also extends the four-bit response code and carries flags such as DO — all in a pseudo-record in the additional section, because the header had no room left. Wire FormatRFC 6891 · INTERNET STANDARD · April 2013
Try it
Look up a record type
Filter by what a type is for, then read its RDATA layout beside the zone-file line that produces it.
29 of 29 types
Addresses
- RDATA
- Four octets, network order.
- Zone file
www.example.com. 300 IN A 203.0.113.10
RFC 1035 §3.4.1
Names and delegation
Service discovery
DNSSEC and verification
Text and metadata
Query and pseudo types
On the wire
Constructed examples, encoded from the field table below them — not captured traffic.
- IP
- Resolver to server, then server to resolver. A response is matched to its query by source address, port, ID and question — all four, because none of them alone is hard to guess. RFC 5452
- UDP or TCP
- Port 53 either way. UDP first, TCP when a reply will not fit — and every server must support both, so a firewall permitting only UDP/53 is a misconfiguration rather than a hardening measure. RFC 7766
- Message
- The header below, then the question section, then answer, authority and additional records — each counted by one of the four fields at the end of the header. RFC 1035
Configure it
$TTL 300 $ORIGIN example.com.The TTL applied to any record that does not state one. It is a promise to every resolver about how long they may keep an answer, so it is the number that decides how long a mistake lasts.
RFC 2308 §4
@ IN SOA ns1.example.com. hostmaster.example.com. ( 2026090801 ; serial 7200 ; refresh 900 ; retry 1209600 ; expire 900 ) ; minimum — negative cache TTLFive timers with almost nothing in common. Refresh, retry and expire govern secondary transfers; minimum governs how long every resolver on the internet may remember that a name in this zone does not exist.
Common mistake: Leaving minimum at the 86400 that most templates ship with. A single premature query then caches NXDOMAIN for the maximum three hours RFC 2308 permits, and there is no way to retract it.
RFC 2308 §4
2026090801 ; serial — increment on every editA secondary compares this against its own copy to decide whether to transfer. Edit the zone without incrementing it and the secondaries stay on the old data with nothing logged as wrong.
Common mistake: Editing the records and forgetting the serial. The primary answers correctly, the secondaries answer stale, and which one a client reaches is chance.
RFC 1995 §2
@ IN NS ns1.example.com. @ IN NS ns2.example.com. ns1 IN A 203.0.113.10 ns2 IN A 198.51.100.10The NS set has to match what the parent zone delegates to, and each name server needs an address record. Those addresses are what the parent serves as glue.
Common mistake: Removing a decommissioned server from the zone but not from the registrar. The delegation still names it, resolvers still try it, and resolution fails for whoever happens to pick it.
RFC 1912 §2.8
www IN A 203.0.113.20 @ IN MX 10 mail.example.com. app IN CNAME www.example.com.Three types answering three different questions about names in this zone. A CNAME is legal here because `app` has no other data at that name.
RFC 2181 §10.1
@ IN HTTPS 1 . alpn="h2,h3"The apex cannot be a CNAME, because it must carry SOA and NS records. An HTTPS record is the standard way to express service parameters at a name that already has data.
Common mistake: Trying to CNAME the apex. Servers reject it or accept it and break the zone; provider-specific "ALIAS" and "flattening" records are workarounds, not standards.
RFC 9460 §2
Verify
named-checkzone example.com /var/named/example.com.zone- Zone parses and the serial is the one you just wrote.
dig @localhost example.com SOA +norecurse- AA set, and the minimum field you configured.
dig @ns2.example.com example.com SOA- The same serial as the primary — otherwise the transfer has not happened.
rndc flushname app.example.com- Removes one cached entry, on this resolver only.
Caveats
- A relative name without a trailing dot has $ORIGIN appended. Writing `www.example.com` instead of `www.example.com.` produces www.example.com.example.com.
- Records with the same name, class and type share one TTL whether the zone file says so or not.
When it breaks
Symptom first, because that is what you have when it happens.
A newly created record does not resolve, and keeps not resolving. Some clients work, others get NXDOMAIN.
Narrow it down
- Query the authoritative server directly with `dig @ns1.example.com name` and confirm the record is there.
- Query the recursive resolver the failing client uses and compare the RCODE.
- Read the SOA minimum for the zone — that is how long the denial lives.
Cause
The name was queried before it existed. The NXDOMAIN was cached with the SOA minimum as its lifetime, and a cached denial is answered from cache without consulting anyone.
Fix
Flush the name on resolvers you control and wait out the rest. Then lower the SOA minimum so the next such mistake is fifteen minutes rather than a day.
- Caching Negative AnswersRFC 2308 · PROPOSED STANDARD · March 1998A lookup "fails" but the name plainly exists. Tooling reports it as not found; a capture shows RCODE 0.
Narrow it down
- Read the RCODE and ANCOUNT separately. NOERROR with ANCOUNT 0 is not NXDOMAIN.
- Ask for the specific type the application needs, not just A.
- Check for an AAAA lookup failing on a name that only has an A record.
Cause
The name exists and has no record of the type requested. This is an empty answer, not a missing name, and the two have different meanings and different cache lifetimes.
Fix
Add the record of the type actually being asked for. If the client is asking for AAAA on an IPv4-only name, the empty answer is correct and the client behaviour is what to look at.
- No DataRFC 2308 · PROPOSED STANDARD · March 1998Most names resolve; a few fail slowly. Failures correlate with DNSSEC-signed zones or names with many records.
Narrow it down
- Compare `dig name` with `dig +tcp name` — if only the second works, TCP is reachable and something is preventing the fallback.
- Look for TC=1 in the UDP reply.
- Test TCP/53 to the server directly and check the firewall policy in both directions.
Cause
A truncated UDP reply requires a TCP retry, and TCP/53 is filtered. Only queries whose answers exceed the advertised buffer are affected.
Fix
Permit TCP/53. Lowering the EDNS buffer makes truncation more predictable but cannot remove the need for TCP.
Transport Protocol SelectionRFC 7766 · PROPOSED STANDARD · March 2016Intermittent SERVFAIL. Resolution succeeds or fails depending on which name server the resolver happens to try.
Narrow it down
- List the NS records in the parent zone and query each one directly.
- Check whether every listed server answers with AA set for the zone.
- Compare the SOA serial across all of them.
Cause
A server named in the delegation is not authoritative for the zone — decommissioned, never configured, or lost the zone. A resolver that picks it gets a referral or a refusal instead of an answer.
Fix
Remove the server from the delegation, or make it authoritative. Both parent and child NS sets need to agree.
Authority and Delegation Errors (NS records)RFC 1912 · INFORMATIONAL · February 1996The primary has the new record and the secondaries do not, indefinitely. No transfer errors are logged.
Narrow it down
- Compare the SOA serial on the primary and each secondary.
- Check whether a NOTIFY was sent and accepted.
- Attempt a transfer by hand and see whether it is authorised.
Cause
The zone was edited without incrementing the serial. A secondary compares serials to decide whether to transfer, so an unchanged serial means there is nothing to fetch.
Fix
Increment the serial. Serial arithmetic is modular, so a serial that went backwards needs care rather than a simple correction.
Brief Description of the ProtocolRFC 1995 · PROPOSED STANDARD · August 1996A short name resolves to the wrong host, or a fully qualified name gets an unexpected suffix appended.
Narrow it down
- Check the resolver search list on the client.
- Query with a trailing dot to force an absolute name and compare.
- Look for a wildcard record in one of the search domains.
Cause
The client appended a search suffix and something answered. A wildcard in a search domain will answer for anything, so the first suffix tried wins.
Fix
Use fully qualified names in configuration, and keep the search list short. A wildcard in a domain that is also a search suffix will catch typos and turn them into successful lookups of the wrong thing.
WildcardsRFC 1034 · INTERNET STANDARD · November 1987
Design notes
Lower the TTL before a change, not after. A record served with a one-hour TTL will be remembered for an hour by resolvers that fetched it a minute ago, and there is no way to recall it. Drop the TTL to a minute, wait an hour, make the change, then put it back.
Set the SOA minimum with the same care as a TTL. It is the negative caching lifetime, so it governs how long a mistake of omission survives — and mistakes of omission are the common kind. - SOA Minimum FieldRFC 2308 · PROPOSED STANDARD · March 1998
A CNAME cannot coexist with other data at the same name, which is why the zone apex — example.com itself, which must have SOA and NS records — cannot be a CNAME. Providers work around this with non-standard flattening, or with the HTTPS and SVCB record types designed for the purpose. CNAME resource recordsRFC 2181 · PROPOSED STANDARD · July 1997
Do not filter TCP/53. Zone transfers require it, DNSSEC answers regularly exceed any sensible UDP buffer, and the resulting failure is selective and slow — the hardest combination to diagnose. Transport Protocol SelectionRFC 7766 · PROPOSED STANDARD · March 2016
Prefer asking for the type you want over asking for ANY. ANY was never a way to enumerate a name — it returns whatever one server happens to hold in cache — and responders are now permitted to answer it with a single synthesised record instead. Behavior of DNS RespondersRFC 8482 · PROPOSED STANDARD · January 2019
Misconceptions
- “NXDOMAIN means the record I asked for does not exist.”
- It means the name does not exist, for any type. If the name exists and has no record of that type you get NOERROR with an empty answer section. The distinction matters because the two are cached differently and point at different mistakes. - Negative ResponsesRFC 2308 · PROPOSED STANDARD · March 1998
- “DNS is a UDP protocol; TCP is a legacy fallback.”
- Both transports have been required since RFC 1123 in 1989. TCP is how zone transfers work and how any answer too large for a datagram is delivered, and DNS over TLS and over HTTPS are TCP-based by construction. Transport Protocol SelectionRFC 7766 · PROPOSED STANDARD · March 2016
- “Lowering the TTL makes a change propagate faster.”
- It makes the next change propagate faster. Resolvers already holding the record keep it for whatever TTL they were given when they fetched it, so the reduction only helps once the old value has expired everywhere.
- “An answer with the AA bit set is the current truth.”
- It means the responding server is authoritative for the question name — that it is answering from a zone file rather than a cache. A stale zone on a secondary that stopped transferring answers with AA set and is wrong. Header section formatRFC 1035 · INTERNET STANDARD · November 1987
- “The AD bit means the answer was cryptographically verified, so I can trust it.”
- It means some resolver says it verified. The bit itself is not signed, so it is only worth as much as the path between you and that resolver. Validating locally is the only version of this that proves anything. The AD and CD Bits in an Authoritative ResponseRFC 4035 · PROPOSED STANDARD · March 2005
- “Querying ANY lists every record at a name.”
- It never did. A cache returns what it happens to hold, an authoritative server returns what it has at that one name, and responders are now allowed to answer with a single synthesised record instead. Ask for the type you want. Behavior of DNS RespondersRFC 8482 · PROPOSED STANDARD · January 2019
More walkthroughs
The record exists and nobody can see itfailure
A new name is added to the zone and stays unresolvable for hours. The record is correct, the zone is loaded, and the resolvers are caching an answer that no longer exists — the absence.
Someone tests app.example.com before the record is added. It does not exist, so the authoritative server says so — NXDOMAIN, with the zone’s SOA in the authority section. Client. Client on another resolver. Resolver A. Resolver B. ns1.example.com: SOA MINIMUM 86400.
- Link
- Blocking
- Packet in flight
- Discarded
- Emphasis
Text equivalent of this diagram
| Element | Kind | State |
|---|---|---|
| Client | host | — |
| Client on another resolver | host | — |
| Resolver A | router | — |
| Resolver B | router | — |
| ns1.example.com | cloud | SOA MINIMUM: 86400 |
| Client — Resolver A | link | up |
| Client on another resolver — Resolver B | link | up |
| Resolver A — ns1.example.com | link | up |
| Resolver B — ns1.example.com | link | up |
Someone tests app.example.com before the record is added. It does not exist, so the authoritative server says so — NXDOMAIN, with the zone’s SOA in the authority section.
The SOA is not decoration. Its MINIMUM field is the lifetime of this denial: it tells every resolver how long it may remember that the name does not exist.
What changed
- A? app.example.com: Resolver A → ns1.example.com
- NXDOMAIN · NSCOUNT 1 (SOA): ns1.example.com → Resolver A
- ns1.example.com: SOA MINIMUM → 86400
Why DNS has two transportsdesign-choice
A reply that will not fit in the requestor’s buffer comes back truncated, and the resolver retries over TCP. Where TCP/53 is blocked, only the names with large answers fail.
DNS asks over UDP because a lookup is one packet each way and a connection setup would triple the latency of the most frequent operation on the internet. Resolver: EDNS buffer 1232. Firewall · UDP/53 only. Signed zone · ns1.
- Link
- Blocking
- Packet in flight
- Discarded
- Emphasis
Text equivalent of this diagram
| Element | Kind | State |
|---|---|---|
| Resolver | router | EDNS buffer: 1232 |
| Firewall · UDP/53 only | firewall | — |
| Signed zone · ns1 | cloud | — |
| Resolver — Firewall · UDP/53 only | link | up · query |
| Firewall · UDP/53 only — Signed zone · ns1 | link | up · permit udp 53 |
DNS asks over UDP because a lookup is one packet each way and a connection setup would triple the latency of the most frequent operation on the internet.
The original limit was 512 octets, which is what fits in a UDP datagram every host is required to reassemble. EDNS(0) lets a requestor advertise a larger buffer in the OPT record, and 1232 is the current common choice: large enough for most signed answers, small enough to stay under the IPv6 minimum MTU and avoid fragmentation.
What changed
- DNSKEY? example.com · EDNS0 1232: Resolver → Signed zone · ns1
- Resolver: EDNS buffer → 1232
Terms
- Authoritative server
- A server answering from a zone it holds rather than from a cache. It sets the AA bit — which says where the answer came from, not that the zone is current.
- Recursive resolver
- A server that walks the delegation from the root on a client’s behalf and caches every step. The cache is why the root servers are not asked about every lookup.
- Delegation
- The NS records by which a parent zone hands responsibility for a subtree to another set of servers. The parent stores where to ask, not the answers.
- Glue record
- An address record a parent zone serves for a name server it does not own, so that resolving the delegation does not require following it first.
- RRset
- All records sharing a name, class and type. It is served, cached, expired and signed as one unit, so every record in it carries the same TTL.