dig, one query per page
Thirty lessons for reading dig output with your own eyes: the four zones of a plain reply and its header, footer and OPT lines, +short and the +noall display switches, address and zone queries from A to SOA, asking the authoritative source directly and reading the aa flag, reverse lookups with -x and in-addr.arpa, the statuses NOERROR empty, NXDOMAIN, SERVFAIL and REFUSED, walking the delegation with +trace, cache evidence in falling and diverging TTLs, and trust: the AD bit, +dnssec signatures and comparing resolvers side by side.
One dig command, its real output, and how to read it. That's a page.
dig, one query per page
Thirty lessons for reading dig output with your own eyes: the four zones of a plain reply and its header, footer and OPT lines, +short and the +noall display switches, address and zone queries from A to SOA, asking the authoritative source directly and reading the aa flag, reverse lookups with -x and in-addr.arpa, the statuses NOERROR empty, NXDOMAIN, SERVFAIL and REFUSED, walking the delegation with +trace, cache evidence in falling and diverging TTLs, and trust: the AD bit, +dnssec signatures and comparing resolvers side by side.
Set in Space Grotesk, Inter and JetBrains Mono (SIL Open Font License).
Every fact in this book is as the official source states it, fetched and read during this build: the dig(1) man page and the BIND 9 Administrator Reference Manual dig chapter, RFC 1034, RFC 1035 and RFC 2308, the Wikipedia articles on the dig command and DNSSEC, and live observed output captured with DiG 9.18.39 on 2026-10-18 (capture files live-dig-capture.txt and extra-capture-child.txt); TTLs quoted are from the capture moment. Demand evidence from live command output, reconfirmed at dispatch; no facts are sourced from Reddit, Stack Overflow or tutorials. An independent guide, not affiliated with or endorsed by the Internet Systems Consortium.
Your purchase is for personal use only. You do not have redistribution rights: please do not share, resell, or republish this book or its pages.
© 2026 Steve Hodgkiss. All rights reserved. Personal use only; no redistribution rights.
Edition 1.0 · stevehodgkiss.net
Contents
Observed live, live capture sec. 1: one plain dig example.com A reply has four zones, the header line, the QUESTION section, the ANSWER section, then the footer lines from Query time to MSG SIZE.
Four sections
Every plain dig reply has the same skeleton, top to bottom: the header line, the QUESTION section, the ANSWER section, the footer lines. The capture shows them all in one screen for example.com A.
The header tells you what happened. The question echoes what you asked. The answer is the payload, here two A records. The footer is the receipt: how long, from whom, when, how many bytes.
Learn the skeleton once and every dig output you ever see becomes navigable.
Run dig example.com A and name the four zones out loud before reading any record.
Per dig(1), +short toggles whether a terse answer is provided; observed live, capture sec. 2: two bare addresses, 104.20.23.154 and 172.66.147.243, and nothing else.
The +short habit
For scripts and quick checks, the whole apparatus is noise. +short prints only the record data, one value per line: two addresses for example.com, nothing else.
The trade is real: no status, no counts, no proof. A typo'd name prints nothing and looks identical to a real empty answer. When debugging, run the plain form too.
+short for consuming, plain dig for understanding. Use each knowing which you are doing.
Resolve three names with +short, then rerun one without it and list what +short hid.
Observed live, capture sec. 1: example.com returned two A records, 104.20.23.154 and 172.66.147.243, each on its own line with TTL 177 at the moment of capture.
Two A answers
Nothing forbids several A records for one name. Here example.com is 104.20.23.154 and 172.66.147.243 at once, two lines, one name, round robin.
Clients usually take the first and cache both. Operationally it means either address must serve: test against both, or one day the other half of the traffic is the outage.
Count the ANSWER lines before you pick an address. The second one is not a backup, it is half the name.
Resolve five names you use daily with +short and count how many return more than one address.
Observed live, capture sec. 4: gmail.com MX returned five records, preferences 5, 10, 20, 30 and 40, printed in arrival order, not preference order.
MX, by preference
The MX number is a cost, not a rank of quality. Preference 5, gmail-smtp-in.l.google.com, is tried first; 40 is the last resort. Lower reaches the mail first.
dig prints the rows in whatever order they arrived, observed 40, 30, 5, 20, 10. Sort by the number when order matters. Equal numbers mean the zone wants the load shared.
When mail flows to the wrong host, this column is the first thing to check.
Ask MX for three mail providers, sort each by preference, and confirm the lowest number is the primary.
Per dig(1), with -x dig performs a lookup for a name like 94.2.0.192.in-addr.arpa and sets the query type and class to PTR and IN; observed live, capture sec. 9: dig -x 1.1.1.1 answered one.one.one.one.
The -x habit
Addresses have names too, and dig has a flag for asking: dig -x 1.1.1.1. No name to type, no type: -x builds the question and sets type PTR, class IN for you.
Everything else is an ordinary query. Observed live: question 1.1.1.1.in-addr.arpa. IN PTR, answer one.one.one.one., TTL 1405, the same four zones as ever.
Logs full of addresses become names with one flag. That is the whole habit.
Run dig -x 8.8.8.8 and dig -x for your own IP, and compare the two QUESTION sections.
Observed live, extra capture E1: dig nxdomain-check-11347.invalid returned status: NXDOMAIN, flags qr aa rd ra ad, ANSWER: 0; per RFC 1035 RCODE 3 is a name error, and per RFC 2308 resolvers negative-cache it.
NXDOMAIN
NXDOMAIN is the strongest no in DNS: this name does not exist, not under this zone, not with any type. Captured live, the .invalid tree answered exactly that, zero answers, flags qr aa rd ra ad.
Two consequences. Per RFC 2308 the no is negative-cached: retrying immediately changes nothing. And in practice the usual cause is a typo, so retype before you diagnose.
When NXDOMAIN is real, it ends the search. When it is yours, it ends the typo.
Run dig nxdomain-check-11347.invalid and read the status, then try a deliberate typo of a real domain.
Per dig(1), +trace toggles tracing of the delegation path from the root name servers and dig makes iterative queries following referrals; observed live, capture sec. 12: root, then net, then cloudflare, four Received lines.
+trace from the root
A normal dig delegates the walking to one resolver. +trace makes dig do the walk itself: start at the root servers, follow each referral down.
Observed live, three hops: the root's 13 NS names, then net. at the gtld servers, then lloyd and mia.ns.cloudflare.com holding stevehodgkiss.net, then the answer. Each hop ends with a Received line naming the server that spoke.
It is the whole lookup chain from the concepts book, now visible, hop by hop, on your own screen.
Run dig stevehodgkiss.net +trace and name each zone that referred you onwards, using the Received lines.
Observed live, capture sec. 16: the same cloudflare.com ask showed flags qr rd ra on one server and qr rd ra ad on another; per RFC 4033, the AD bit hints that the recursive server validated the response signatures.
The AD bit
One letter in the flags line changes what a reply is worth. ad, authentic data: the resolver says it checked the signatures on this answer, the whole chain.
Observed live, the same name came back qr rd ra from one server and qr rd ra ad from another. The record was identical; the trustworthiness travelled separately, from the validating resolver.
No ad does not mean fake. It means this resolver does not vouch. Ask a validating one before concluding.
Ask a signed domain through @1.1.1.1 with +dnssec and find ad in the flags; check whether your default resolver sets it.