dig

dig asks a DNS server a direct question and prints exactly what it answers: the addresses a name resolves to, its mail and name servers, the TTLs, and the header status flags. Reach for it when you want DNS ground truth instead of whatever a browser or a cached lookup decides to show you, whether that is an early recon pass, verifying a homelab record, or answering “is that record actually pointing where I think it is?”

Mental model: dig [@resolver] name [type] [+options]. Omit the type and you get an A record; omit the resolver and it uses your system default.

New to DNS? Core concepts
  • Record type: what you are asking for. A (IPv4), AAAA (IPv6), MX (mail), NS (name servers), TXT (SPF/DMARC), SOA (zone info), CNAME (alias), PTR (reverse)
  • ANSWER section: the records that actually answer your query; each line reads name, TTL, class, type, value
  • Resolver vs authoritative: a resolver (@server) may reply from cache; the zone’s own NS is the source of truth, and the aa flag means the answer is authoritative
  • TTL: how many seconds a record may be cached before a fresh lookup; it is the number right before the type
  • Recursion: you ask a resolver to chase the whole chain for you (rd/ra flags); +trace walks it hop by hop yourself
  • status: the header outcome. NOERROR (worked), NXDOMAIN (no such name), SERVFAIL (broken), REFUSED (declined)
  • Reverse lookup (PTR): an IP back to a name, the opposite direction from A/AAAA
When to reach for dig (and when not)

Reach for it when you want DNS ground truth instead of a cached or browser-massaged answer: an early recon pass, confirming a record points where you think, reading SPF/DMARC TXT, finding a domain’s MX and NS, reverse-lookups, or tracing which hop breaks a lookup with +trace.

Reach for something else when you just need one quick line (host), DNS-over-TLS or DNS-over-HTTPS (kdig), or heavy DNSSEC debugging (drill). Once you have the records, whois adds registration and ownership context and nmap scans the addresses dig resolved to find live services.

Install, update, verify#

dig ships inside the DNS utilities package, not a package named “dig”.

sudo apt install -y dnsutils                    # Debian / Ubuntu / Kali
sudo dnf install -y bind-utils                  # Fedora / RHEL
brew install bind                               # macOS
sudo apt install --only-upgrade -y dnsutils     # update

dig -v            # version (note: -v, not --version)
command -v dig    # confirm it is on PATH

On Windows, use the dig that ships with WSL or install ISC’s BIND tools. A one-off dig with no arguments queries the root servers (. NS) and is a quick “is DNS working at all?” smoke test.

Flags you’ll actually use#

Skim these first; the cheat sheet below is these flags combined.

FlagDoesFlagDoes
@serverQuery a specific resolver+shortValues only, one per line
-x IPReverse (PTR) lookup+noall +answerAnswer section only
-t TYPESet the type explicitly+traceFollow delegation from root
-q NAMESet the name explicitly+norecurseAsk cache only, no chasing
-p PORTNon-standard DNS port+dnssecRequest RRSIG records
-f FILEBatch queries from a file+cdChecking disabled (skip DNSSEC)
-4 / -6Force IPv4 / IPv6 transport+tcpForce TCP (AXFR, truncation)
+multilineExpand SOA / DNSKEY records+time=N +tries=NTimeout and retry budget

-t and -q only matter when a name could be mistaken for a type; normally the positional order handles it.

Cheat sheet#

The first block trims verbosity one line at a time, so you can stop where the noise level is right. The rest swap one field (the type, the resolver, an option) per line.

# Trim the noise: stop at the line you need
dig DOMAIN                        # 1. full response: header, question, answer, stats
dig DOMAIN +noall +answer         # 2. + just the answer section
dig +short DOMAIN                 # 3. + values only, one per line (A is the default type)

# Records (swap the type)
dig DOMAIN A                      # IPv4 address
dig DOMAIN AAAA                   # IPv6 address
dig DOMAIN MX                     # mail servers + priorities
dig DOMAIN NS                     # authoritative name servers
dig DOMAIN TXT                    # SPF / DMARC / verification strings
dig DOMAIN SOA                    # zone serial + primary NS
dig DOMAIN CNAME                  # alias target
dig _sip._tcp.DOMAIN SRV          # service host + port (note the _svc._proto prefix)
dig DOMAIN CAA                    # which CAs may issue certs for the domain
dig DOMAIN DNSKEY                 # zone signing keys (signed zones)

# Concise output
dig +short DOMAIN MX              # values only, any type
dig +noall +answer DOMAIN         # answer section only, no header / stats
dig +multiline DOMAIN SOA         # expand SOA / DNSKEY into labelled lines
dig +noall +answer DOMAIN A DOMAIN MX DOMAIN NS   # several types, one run

# Pick the resolver
dig @RESOLVER DOMAIN A            # ask a specific server (e.g. @1.1.1.1)
dig @RESOLVER DOMAIN A +short     # compare against your system default
dig -p 5353 @RESOLVER DOMAIN A    # non-standard DNS port

# Reverse
dig -x TARGET_IP +short           # IP -> hostname (PTR)

# Debug and delegation
dig +trace DOMAIN                 # follow delegation root -> TLD -> authoritative
dig DOMAIN A +norecurse @RESOLVER # what this resolver has cached (no chase)
dig +dnssec DOMAIN A              # show RRSIG records on signed zones
dig +cd DOMAIN A                  # checking disabled: fetch even if DNSSEC fails
dig +tcp DOMAIN A                 # force TCP instead of UDP

# Batch and tuning
dig -f names.txt +short           # one query per line from a file
dig DOMAIN A +time=2 +tries=1     # fail fast: 2s timeout, no retries

# Zone transfer (lab / owned only)
dig @RESOLVER DOMAIN AXFR         # full zone if misconfigured; usually REFUSED

Command breakdowns#

Each block below explains one situation, the exact command, and what to expect back.

Resolve a name to its IPv4 address#

dig DOMAIN A

An ANSWER SECTION with one or more A records. The number before the type is the TTL in seconds, and multiple A lines usually mean round-robin or a load balancer.

Get just the IP, nothing else#

dig +short DOMAIN

Bare addresses, one per line. A is the default type, so you can drop it. Ideal inside $(...) and shell loops where you only want the value.

Look up IPv6 addresses#

dig DOMAIN AAAA

AAAA records if present. An empty answer with NOERROR means the name simply has no IPv6, not a failure.

Find a domain’s mail servers#

dig DOMAIN MX +short

Each line is <priority> <host>; the lowest priority number is tried first. Feed those hostnames back into dig ... A to get the actual mail server IPs.

Read SPF, DMARC, and verification records#

dig DOMAIN TXT
dig _dmarc.DOMAIN TXT

SPF lives in the apex TXT (v=spf1 ...); DMARC sits under the _dmarc label. Long values arrive split across multiple quoted chunks, so concatenate them before parsing.

Find the authoritative name servers#

dig DOMAIN NS +short

The servers that own the zone. Query one of these with @ to get answers straight from the source instead of a cache.

Check the zone serial (SOA)#

dig DOMAIN SOA +noall +answer

The serial (often YYYYMMDDnn) tells you whether a change was actually published; the refresh, retry, expire, and minimum values follow it on the same line.

Query a specific resolver and compare answers#

dig @RESOLVER DOMAIN A +short

Points at one server instead of your default. Different answers between two resolvers means caching, split-horizon DNS, or geo-routing, not necessarily a mistake.

Check what a resolver has cached#

dig DOMAIN A +norecurse @RESOLVER

+norecurse sets rd=0, so a recursive resolver answers only from its cache instead of chasing the chain. An empty answer means it has not cached that record yet.

Reverse-lookup an IP to a hostname#

dig -x TARGET_IP +short

Returns the PTR record if one is configured. Many hosts have none, so an empty result here is normal, not an error.

Follow a CNAME chain to the real record#

dig DOMAIN A +noall +answer

If the name is an alias you will see the CNAME line, then the A it points to. Do not stop at the CNAME; the address is one hop further down.

Trace resolution from the root down#

dig +trace DOMAIN

Walks root -> TLD -> authoritative, printing each delegation, and bypasses your recursive resolver’s cache. Noisy, but it shows exactly which hop breaks a lookup.

Attempt a zone transfer (lab targets only)#

dig @RESOLVER DOMAIN AXFR

Dumps the entire zone if the server is misconfigured to allow it; a correct server answers REFUSED or Transfer failed. Only against infrastructure you own or are explicitly authorized to test.

Check DNSSEC signatures#

dig +dnssec DOMAIN A

Adds RRSIG records beside the answer on a signed zone. The ad flag in the header means the resolver validated them; use +cd to fetch the data even when validation would fail.

Query several records in one run#

dig +noall +answer DOMAIN A DOMAIN MX DOMAIN TXT DOMAIN NS

dig processes each name/type pair in sequence and prints one combined block, giving a fast full-record snapshot without four separate invocations.

Look up SRV or CAA records#

dig _sip._tcp.DOMAIN SRV
dig DOMAIN CAA

SRV maps a service to host plus port (note the _service._proto prefix); CAA lists which certificate authorities may issue certs for the domain.

Reading the output#

An ANSWER line reads left to right as name, TTL, class, type, value:

DOMAIN.   3600   IN   A   198.51.100.10

The header’s status: is the outcome; read it as carefully as the answer:

statusMeaningDo next
NOERROR + answerRecords exist; these are your factsRead them
NOERROR, emptyName exists, but no record of that typeQuery a different type (MX, TXT, NS)
NXDOMAINName does not exist from this resolver’s viewCheck spelling; try another resolver
SERVFAILResolver could not complete the query+trace, or query the authoritative NS
REFUSEDResolver declinedNormal on AXFR; otherwise you are off its allow-list

Header flags: aa = authoritative (not a cache), ad = DNSSEC-validated, rd/ra = recursion desired / available, tc = truncated (retry with +tcp).

Troubleshooting#

ProblemCauseFix
command not founddnsutils not installed / stale PATHInstall dnsutils (or bind-utils); open a fresh shell
connection timed out; no servers could be reachedNo resolver or no networkCheck /etc/resolv.conf; try dig @RESOLVER
status: NXDOMAINName truly does not existVerify spelling; try another resolver
status: SERVFAILBroken delegation or DNSSECUse +trace; query the authoritative NS directly
status: REFUSED on AXFRServer blocks zone transfer (normal)Expected on secure servers; only test lab targets
Empty answer, NOERRORNo record of that typeQuery a different type (A, MX, TXT, NS)
;; Truncated, retrying in TCPUDP reply too largeLet dig retry, or force it with +tcp
Answers differ between resolversCaching, split DNS, or geo-routingCompare default vs @RESOLVER; check TTL and the aa flag

Gotchas#

  • There is no package called “dig”. It lives in dnsutils (Debian) or bind-utils (RHEL), so a search for a “dig” package finds nothing.
  • NOERROR with an empty answer is not NXDOMAIN. The name exists; it just has no record of the type you asked for. Query the right type before declaring DNS broken.
  • +short hides the status line. An empty result could be no record, the wrong name, or the wrong resolver. Re-run without it to see NOERROR vs NXDOMAIN.
  • A cached answer is not authoritative. No aa flag means it came from a cache, so query the zone’s NS (or @RESOLVER) for the source of truth.
  • ANY is mostly dead. Resolvers now minimize or refuse it (RFC 8482), so query specific types instead of hoping one lookup returns everything.
  • +trace ignores your resolver. It starts at the root, so it will not reproduce a cache or split-horizon answer your applications actually see; use @RESOLVER for that.

Pairs with#

whois adds registration and ownership context to the records dig returns, and nmap scans the addresses dig resolves to find live services. For a quick one-liner reach for host; for DNS-over-TLS or DNS-over-HTTPS use kdig; for heavy DNSSEC debugging drill is purpose-built. dig stays the universal, scriptable default for everything in between.

Find us elsewhere

Merch, stickers, and moreSupport the work at the Solvere Labs shop