All of the portfolio
Portfolio · Task / journey-based

User-flow structure

A sample documentation set for dig, The DNS lookup utility from the BIND tools.

Why this structure

dig is learned one flag at a time. Ordering the documentation as a journey, from a first lookup to tracing a full resolution, lets a reader follow along at their own terminal and build up, which suits a command-line tool you explore interactively rather than read cover to cover.

Get docs like this
Appdig
AboutThe DNS lookup utility from the BIND tools.
StructureTask / journey-based
AudienceDevelopers, sysadmins and anyone debugging DNS.
Size4 sections · 9 pages
Browse the documentation

A real, navigable sample

This is the actual structure, with example articles. Click any page in the sidebar to read it.

bind9.readthedocs.io
1 · Get started

Install dig

dig, the Domain Information Groper, ships as part of the BIND DNS utilities. On most systems you install a small package to get it.

Install the package

  • Debian / Ubuntu: sudo apt install dnsutils
  • Fedora / RHEL / CentOS: sudo dnf install bind-utils
  • Arch: sudo pacman -S bind
  • macOS: a version of dig is preinstalled; for the latest, brew install bind

Confirm it works

dig -v

This prints the version. If the command is found, you are ready.

On Windows dig is not built in. Install it through the BIND tools for Windows, or use nslookup, which ships with the OS and covers the basics.
1 · Get started

Run your first lookup

The simplest use of dig is to ask for a domain's address.

Make a query

dig example.com

By default dig requests the A record, the IPv4 address, and prints a full diagnostic report. Read it from the top:

  • HEADER: the outcome, such as status: NOERROR, plus flags.
  • QUESTION SECTION: the exact question dig asked.
  • ANSWER SECTION: the records that answer it. Each line shows the name, a TTL in seconds, the class (IN), the type (A), and the value.
  • Query time / SERVER: how long it took and which resolver replied.

What success looks like

A status: NOERROR with at least one line in the answer section means the lookup worked.

The number just before IN on an answer line is the TTL: how long a resolver may cache this record before asking again. A low TTL means changes propagate quickly.
2 · Look things up

Query specific record types

DNS holds more than addresses. Ask for a specific record type by naming it after the domain.

Common types

dig example.com MX      # mail servers
dig example.com AAAA    # IPv6 address
dig example.com TXT     # text records, such as SPF
dig example.com NS      # the domain's name servers
dig example.com SOA     # start of authority, the zone's master record
dig example.com CNAME   # an alias to another name

You can request any DNS record type this way.

A note on ANY

dig example.com ANY once returned every record at once. Most servers no longer honour it, to reduce abuse, so query the specific types you need instead.

Reading TXT records is the usual way to check email authentication (SPF, DKIM, DMARC) and domain-ownership verifications, all of which live in TXT.
2 · Look things up

Query a specific DNS server

By default dig asks whatever resolver your system is configured to use. Put @server before the name to ask a specific one instead.

Ask a public resolver

dig @8.8.8.8 example.com          # Google
dig @1.1.1.1 example.com AAAA     # Cloudflare

Ask the authoritative server

To see the source of truth, find the domain's name servers, then query one directly:

dig example.com NS +short
dig @a.iana-servers.net example.com

Why it matters

This is how you check whether a change has taken effect. The authoritative server shows the new value immediately, while public resolvers may still serve a cached copy until its TTL expires.

If @8.8.8.8 and the authoritative server disagree, you are almost certainly looking at caching, and the difference clears when the old record's TTL runs out.
2 · Look things up

Trim the output with +short

The full report is useful for diagnosis but noisy when you just want a value. dig has options to control what it prints.

Just the answer

dig +short example.com

This prints only the answer values, one per line. It is ideal in scripts:

ip=$(dig +short example.com | head -n1)

Keep the answer, drop the rest

dig +noall +answer example.com

This shows the full answer lines (with TTL and type) but hides the header, question and footer.

Combine options

The + options stack, so you can build exactly the view you want. +short is the one you will reach for most often.

Because +short prints nothing but the value, an empty result is a clear signal that no record of that type exists.
3 · Go deeper

Reverse (PTR) lookups

A normal lookup goes from a name to an address. A reverse lookup goes the other way, from an IP address back to a name, using a PTR record.

Use -x

dig -x 8.8.8.8

dig builds the special reverse-lookup name for you (IPv4 addresses are queried under in-addr.arpa, IPv6 under ip6.arpa) and requests the PTR record.

Where it is used

  • Checking the identity a mail server presents, since many mail systems verify reverse DNS.
  • Making sense of a log full of IP addresses.
  • Confirming that a server's forward and reverse records match.
Reverse DNS is controlled by whoever owns the IP address block, usually your hosting provider or ISP, not by the domain owner. A missing PTR is common and often expected for home connections.
3 · Go deeper

Trace the full resolution path

Normally you ask one resolver for the final answer. With +trace, dig shows the whole journey, resolving the name from scratch the way the internet does.

Run a trace

dig +trace example.com

Instead of trusting a single resolver, dig starts at the root name servers and follows the referrals down: the root servers point to the servers for .com, which point to the authoritative servers for example.com, which give the final answer.

Reading a trace

Each block in the output is one step down the hierarchy. You can see exactly which level responds and what it hands off to next.

+trace is the fastest way to find where resolution breaks. If the chain stops at the .com level, the problem is delegation. If it reaches the authoritative servers but returns the wrong record, the problem is in the zone itself.
4 · Troubleshoot

Read the status and flags

The HEADER line summarises what the server said. Learning the few common values makes most DNS problems obvious.

Status values

  • NOERROR: the query succeeded. There may still be no records of the type you asked for; that is not an error.
  • NXDOMAIN: the name does not exist at all.
  • SERVFAIL: the server tried but failed, often a broken zone, a lame delegation, or a DNSSEC validation problem.
  • REFUSED: the server declined to answer, for example because it does not serve that zone.

Flags

The flags line, such as flags: qr rd ra, tells you more:

  • qr: this is a response.
  • rd: recursion was desired.
  • ra: recursion is available at that server.
  • aa: the answer is authoritative, straight from the zone's own server.
NOERROR with an empty answer section is the single most misread result. It means the name exists but has no record of that type, so try a different type.
4 · Troubleshoot

Common problems and fixes

A short checklist for when DNS is not behaving.

No answer, but NOERROR

The name exists but has no record of the type you requested. Try another type, or check whether the record was actually created.

NXDOMAIN

The name does not exist. Check the spelling, check you queried the right domain, and confirm the record was published.

Stale or wrong value

You are probably seeing a cached copy. Query the authoritative server directly with @, and remember the TTL controls how long resolvers hold the old value before refreshing.

Different answers from different resolvers

dig @1.1.1.1 example.com +short
dig @8.8.8.8 example.com +short

If these disagree, it is caching or a mid-propagation change. Use dig +trace to find the authoritative answer everything will eventually agree on.

When in doubt, work from the authoritative server outward. It is the source of truth; everything else is a cache of it.