> ## Content Index
> Fetch the complete content index at: https://www.pinglabz.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# dig: The Complete DNS Query Guide
- URL: https://www.pinglabz.com/dig-command/
- Published: 2026-08-19T14:25:11.000Z
- Updated: 2026-08-19T18:24:25.000Z
- Description: Read the status line first. Flags, sections, TTLs, delegation traces and DNSSEC, all against a real authoritative server in the lab.
- Author: Jaime
- Tags: Linux, DNS, Troubleshooting, Labs

Half the outages that get reported as "the network is down" are DNS, and `dig` is how you prove it in under ten seconds. It is the only DNS client on a Linux box that shows you the entire response: the header flags, the status code, which section each record came from, how long the answer took and which server actually answered. `host` and `nslookup` both hide most of that.

This guide works through `dig` against a real authoritative server. Everything below is genuine output from a Debian 13 host wired into a Cisco Modeling Labs topology, querying a lab DNS server four hops away that is authoritative for the zone `pinglabz.lab`, plus live queries out to public resolvers where the real internet makes the point better. It is part of the [Linux networking commands](https://www.pinglabz.com/linux-networking-commands/) cluster.

## The lab behind every capture

The client is a Debian 13 host at 10.77.0.100\. The DNS server is a container at 10.77.3.10 running a small authoritative server for `pinglabz.lab`, reachable across three IOS XE routers running OSPF. Nothing is cached anywhere in between, so query times are honest:

```
j@llmbits:~$ traceroute -n 10.77.3.10
traceroute to 10.77.3.10 (10.77.3.10), 30 hops max, 60 byte packets
 1  10.77.0.1  5.484 ms  5.742 ms  5.856 ms
 2  10.77.12.2  4.539 ms  6.233 ms  6.119 ms
 3  10.77.23.3  5.961 ms  6.698 ms  6.811 ms
 4  10.77.3.10  5.983 ms  6.341 ms  7.078 ms
```

The zone carries A, AAAA, MX, TXT, NS, SOA, SRV, CNAME and PTR records, and it refuses zone transfers, which turns out to be a useful thing to demonstrate.

## Reading a full dig answer

Run `dig` with no options and you get the whole response. This is the form to use when something is wrong, because every field is a clue:

```
j@llmbits:~$ dig @10.77.3.10 pinglabz.lab

; <<>> DiG 9.20.26-1~deb13u1-Debian <<>> @10.77.3.10 pinglabz.lab
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 61500
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;pinglabz.lab.			IN	A

;; ANSWER SECTION:
pinglabz.lab.		3600	IN	A	10.77.3.10

;; Query time: 8 msec
;; SERVER: 10.77.3.10#53(10.77.3.10) (UDP)
;; WHEN: Wed Aug 19 07:01:20 PDT 2026
;; MSG SIZE  rcvd: 69
```

Six things in there are worth knowing by sight:

**`status:`**The RCODE. `NOERROR`, `NXDOMAIN`, `SERVFAIL` and `REFUSED` are four completely different problems and people routinely confuse them. 

**`flags: qr aa rd`**`qr` is "this is a response". `aa` means the server is authoritative for this zone (if it is missing, you are talking to a cache). `rd` is "recursion desired", set by you. `ra` would be "recursion available", set by the server. `ad` means DNSSEC validated. 

**Section counts**`ANSWER: 1` with `status: NOERROR` is a real answer. `ANSWER: 0` with `NOERROR` is NODATA, which means the name exists but not for that record type. 

**TTL**The `3600` column. From an authoritative server it is the configured value. From a cache it counts down, which is how you tell the two apart without reading the flags. 

**`SERVER:`**Which resolver answered, and over which transport. If you did not use `@`, this tells you what `/etc/resolv.conf` actually pointed at, which is not always what you assumed. 

**`Query time`**Round trip in milliseconds. Compare a cold query against a warm one to prove whether a cache is doing its job. 

That `WARNING: recursion requested but not available` line trips people up. It is not an error. `dig` sets `rd` by default, the server is authoritative and does not do recursion, so it does not set `ra`, and `dig` mentions the mismatch. Against a real authoritative nameserver you will see it constantly.

## The output modifiers you will actually use

The full output is for diagnosis. For everything else you want less. `dig` has dozens of `+` options; five of them cover almost all real use:

**`+short`**Just the rdata, one per line. The scripting form. 

**`+noall +answer`**The answer section with names and TTLs, nothing else. The everyday form. 

**`+noall +comments`**Header and flags only. Use it when you care about the status code and not the data. 

**`+stats`**Query time, server, transport and message size. Add it to any of the above. 

**`+multiline`**Breaks structured records apart with labels. Only really matters for SOA and DNSKEY. 

`+noall` switches every section off, then you switch back on the ones you want. That is why the idiom is always `+noall +answer` and never just `+answer`:

```
j@llmbits:~$ dig @10.77.3.10 pinglabz.lab MX +noall +answer
pinglabz.lab.		3600	IN	MX	10 mail.pinglabz.lab.
pinglabz.lab.		3600	IN	MX	20 mail2.pinglabz.lab.

j@llmbits:~$ dig @10.77.3.10 pinglabz.lab MX +short
10 mail.pinglabz.lab.
20 mail2.pinglabz.lab.

j@llmbits:~$ dig @10.77.3.10 pinglabz.lab TXT +short
"v=spf1 ip4:10.77.3.10 ip4:10.77.2.10 -all"
"pinglabz-lab-verification=phase3"
```

`+multiline` earns its keep on exactly one record type. An SOA on one line is unreadable; broken apart it is a checklist:

```
j@llmbits:~$ dig @10.77.3.10 pinglabz.lab SOA +multiline

;; ANSWER SECTION:
pinglabz.lab.		3600 IN	SOA ns1.pinglabz.lab. hostmaster.pinglabz.lab. (
				2026081901 ; serial
				7200       ; refresh (2 hours)
				3600       ; retry (1 hour)
				1209600    ; expire (2 weeks)
				3600       ; minimum (1 hour)
				)
```

The serial is the field you care about in practice. When a secondary disagrees with a primary, comparing serials across both is the first check, and `+multiline` is what makes that readable at a glance.

## Choosing the server with @

`@server` sends the query directly to that address and bypasses `/etc/resolv.conf` entirely. This is the single most useful thing `dig` does, because it splits one question into two:

- Does the name resolve correctly when you ask the authoritative server directly?
- Does it resolve correctly through the resolver this host is actually configured to use?

If the first works and the second does not, the zone is fine and your resolver path is broken. That distinction saves an enormous amount of time. Compare the same name asked three ways:

```
j@llmbits:~$ dig www.pinglabz.lab +noall +answer +stats
www.pinglabz.lab.	3600	IN	A	10.77.2.10
;; Query time: 8 msec
;; SERVER: 10.77.3.10#53(10.77.3.10) (UDP)

j@llmbits:~$ dig @9.9.9.9 pinglabz.com A +noall +answer +stats
pinglabz.com.		14400	IN	A	178.128.137.126
;; Query time: 92 msec
;; SERVER: 9.9.9.9#53(9.9.9.9) (UDP)
;; MSG SIZE  rcvd: 57
```

You can also name the server rather than address it, but be careful: `dig @ns1.example.com` has to resolve `ns1.example.com` first, using your normal resolver. If that resolver is the thing you are debugging, use an address.

## Record types and what you would ask for

The record type goes after the name. Leave it off and you get A. These are the ones worth having in your fingers:

**A / AAAA** Name to IPv4 or IPv6 address. A missing AAAA is not an error, it is a design choice, and telling those apart matters on dual-stack hosts. 

**CNAME** An alias. Cannot coexist with other records at the same name, which is why apex CNAMEs are illegal and why every CDN has a workaround for it. 

**MX** Mail exchangers with a preference number. Lower wins. First stop for "we are not receiving email". 

**TXT** Free text, now load-bearing: SPF, DKIM, DMARC and every vendor's domain verification string lives here. 

**NS** Which servers are authoritative. Query it at the parent and at the child; a mismatch is a real and common fault. 

**SOA** Zone metadata: primary server, contact, serial and the timers. Also what a server returns in the authority section when it says no. 

**SRV** Service location: priority, weight, port, target. Active Directory, SIP and Kubernetes service discovery all run on it. 

**PTR** Reverse mapping, under `in-addr.arpa`. Use `dig -x` and let dig build the name for you. 

SRV answers are where the additional section earns its place. Ask for the service and the server hands you the target's address in the same packet, so the client does not need a second round trip:

```
j@llmbits:~$ dig @10.77.3.10 _sip._udp.pinglabz.lab SRV

;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 2

;; ANSWER SECTION:
_sip._udp.pinglabz.lab.	3600	IN	SRV	10 60 5060 srv1.pinglabz.lab.

;; ADDITIONAL SECTION:
srv1.pinglabz.lab.	3600	IN	A	10.77.3.10
```

Read that as: priority 10, weight 60, port 5060, target `srv1.pinglabz.lab`. Priority works like MX (lower wins), and weight distributes load between equal-priority targets.

## CNAME chasing, and what +short hides

When a name is an alias, a well-behaved server returns the CNAME and the resolved record together. `dig` shows you both:

```
j@llmbits:~$ dig @10.77.3.10 portal.pinglabz.lab

;; ANSWER SECTION:
portal.pinglabz.lab.	3600	IN	CNAME	www.pinglabz.lab.
www.pinglabz.lab.	3600	IN	A	10.77.2.10

j@llmbits:~$ dig @10.77.3.10 portal.pinglabz.lab +short
www.pinglabz.lab.
10.77.2.10
```

Note what `+short` does here: it prints the chain, not just the address. If you are scripting and expecting one line of IP, a CNAME will surprise you. Pipe through `tail -1`, or ask for the record type you actually want.

Real-world chains get longer. This is the live front end of this site, resolved through Quad9:

```
j@llmbits:~$ dig @9.9.9.9 www.pinglabz.com +noall +answer
www.pinglabz.com.	14400	IN	CNAME	ping-labz.ghost.io.
ping-labz.ghost.io.	300	IN	CNAME	ghost.map.fastly.net.
ghost.map.fastly.net.	13	IN	A	151.101.195.7
ghost.map.fastly.net.	13	IN	A	151.101.67.7
ghost.map.fastly.net.	13	IN	A	151.101.3.7
ghost.map.fastly.net.	13	IN	A	151.101.131.7
```

Two CNAMEs deep into a CDN, with a 13 second TTL on the final answer because the CDN wants to move you at will. The descending TTLs (14400, then 300, then 13) tell you these came from a cache, not from an authority.

## Reverse lookups with -x

Reverse DNS lives in a real zone, `in-addr.arpa`, with the octets reversed. `dig -x` builds that name for you:

```
j@llmbits:~$ dig @10.77.3.10 -x 10.77.3.10

;; QUESTION SECTION:
;10.3.77.10.in-addr.arpa.	IN	PTR

;; ANSWER SECTION:
10.3.77.10.in-addr.arpa. 3600	IN	PTR	srv1.pinglabz.lab.

;; ADDITIONAL SECTION:
srv1.pinglabz.lab.	3600	IN	A	10.77.3.10
```

The question section shows the translation, which is worth seeing once so the format stops being mysterious. Forward and reverse are independent: nothing forces them to agree, and plenty of infrastructure has forward records with no reverse at all. Mail servers care, logging systems care, and almost nothing else does.

## NXDOMAIN, NODATA, SERVFAIL, REFUSED

Four failures, four different causes. Getting these straight is most of what separates a fast DNS diagnosis from a slow one:

**NXDOMAIN** The name does not exist, at all, for any type. Authoritative and final. Check your spelling, then check the zone. 

**NOERROR, ANSWER: 0** NODATA. The name exists but has no record of that type. Very common with AAAA on IPv4-only hosts. 

**SERVFAIL** The server tried and could not answer. Broken delegation, unreachable authority, or DNSSEC validation failure. Not your client's fault. 

**REFUSED** The server will not answer you. Wrong zone, or an access control list that does not include your source address. A policy problem, not a data problem. 

NXDOMAIN puts the zone's SOA in the authority section, which is how a resolver knows how long to cache the negative answer (the SOA minimum field):

```
j@llmbits:~$ dig @10.77.3.10 nothere.pinglabz.lab

;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 29605
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; AUTHORITY SECTION:
pinglabz.lab.		3600	IN	SOA	ns1.pinglabz.lab. hostmaster.pinglabz.lab. 2026081901 7200 3600 1209600 3600
```

NODATA looks almost identical, and the difference is entirely in the status line. Here `gw.pinglabz.lab` definitely exists, it just has no AAAA:

```
j@llmbits:~$ dig @10.77.3.10 gw.pinglabz.lab AAAA

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 28530
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; AUTHORITY SECTION:
pinglabz.lab.		3600	IN	SOA	ns1.pinglabz.lab. hostmaster.pinglabz.lab. 2026081901 7200 3600 1209600 3600
```

Same shape, same sections, one word different. Read the status line first, always.

## UDP, TCP and the truncation fallback

DNS uses UDP until the response is too large, then falls back to TCP. You can watch that happen. A plain A query is small and stays on UDP; an ANY query against the same zone is 625 bytes and goes to TCP:

```
j@llmbits:~$ dig @10.77.3.10 pinglabz.lab +noall +stats
;; Query time: 8 msec
;; SERVER: 10.77.3.10#53(10.77.3.10) (UDP)
;; MSG SIZE  rcvd: 69

j@llmbits:~$ dig @10.77.3.10 pinglabz.lab ANY +noall +stats
;; Query time: 4 msec
;; SERVER: 10.77.3.10#53(10.77.3.10) (TCP)
;; MSG SIZE  rcvd: 625
```

On the wire it is unambiguous. A UDP question and answer, then a full TCP handshake before the large response:

```
j@llmbits:~$ sudo tcpdump -ni ens224 -c 8 port 53
07:09:44.979699 IP 10.77.0.100.57465 > 10.77.3.10.53: 59464+ [1au] A? pinglabz.lab. (53)
07:09:44.986325 IP 10.77.3.10.53 > 10.77.0.100.57465: 59464*- 1/0/1 A 10.77.3.10 (69)
07:09:45.039476 IP 10.77.0.100.53102 > 10.77.3.10.53: Flags [S], seq 4156715581, win 64660
07:09:45.044277 IP 10.77.3.10.53 > 10.77.0.100.53102: Flags [S.], seq 299488671, ack 4156715582
07:09:45.044371 IP 10.77.0.100.53102 > 10.77.3.10.53: Flags [.], ack 1, win 506
07:09:45.044578 IP 10.77.0.100.53102 > 10.77.3.10.53: Flags [P.], seq 1:56, length 55 29578+ [1au] ANY? pinglabz.lab. (53)
07:09:45.050735 IP 10.77.3.10.53 > 10.77.0.100.53102: Flags [P.], length 627 29578*- 9/0/5 SOA, NS ns1.pinglabz.lab., NS ns2.pinglabz.lab., A 10.77.3.10, AAAA 2001:db8:77:3::10, MX mail.pinglabz.lab. 10, MX mail2.pinglabz.lab. 20, TXT "v=spf1 ip4:10.77.3.10 ip4:10.77.2.10 -all", TXT "pinglabz-lab-verification=phase3" (625)
```

This is why a firewall that permits UDP 53 but blocks TCP 53 causes intermittent, size-dependent DNS failures. Small lookups work, large ones hang, and the symptom looks random until you check the rule.

The relevant options:

**`+tcp`**Force TCP from the start. The direct way to test whether TCP 53 is permitted end to end. 

**`+ignore`**Do not retry over TCP on truncation. Use it to see the truncated UDP response as it was. 

**`+bufsize=N`**Advertise a smaller EDNS0 buffer, which forces truncation sooner. Useful for reproducing a middlebox that drops large UDP. 

**`+noedns`**Send a plain 512-byte DNS query with no OPT record. If EDNS0 is being mangled in the path, this is the A/B test. 

`+noedns` is worth demonstrating because the difference shows up in the additional count. With EDNS0 the OPT pseudo-record is there, without it the count drops to zero:

```
j@llmbits:~$ dig @10.77.3.10 pinglabz.lab +noedns +noall +comments
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 47281
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
```

Get the Linux Networking Field Reference - 10 pages, free

Every command in this cluster on ten printable pages: iproute2, sockets, DNS, capture, monitors and all three firewall front ends. Includes a ten-symptom troubleshooting decision tree and annotated real lab output. Free for PingLabz members, just sign up with your email.

[Get the Linux networking cheat sheet](https://www.pinglabz.com/linux-networking-cheatsheet/)

## Timeouts, retries and dead resolvers

By default `dig` waits five seconds and tries three times, which is a long wait when you are just checking whether a server is alive. Cut it down:

```
j@llmbits:~$ dig @10.77.9.9 pinglabz.lab +time=2 +tries=1
;; communications error to 10.77.9.9#53: host unreachable

; <<>> DiG 9.20.26-1~deb13u1-Debian <<>> @10.77.9.9 pinglabz.lab +time=2 +tries=1
;; no servers could be reached
```

"No servers could be reached" is not a DNS error, it is a reachability error. There is no RCODE because there was no response. That is a completely different investigation from a SERVFAIL, and the wording is your clue.

## Following the delegation chain

`+trace` starts at the root and walks down, doing the resolver's job one step at a time in front of you:

```
j@llmbits:~$ dig +trace pinglabz.com A
.			79135	IN	NS	a.root-servers.net.
[... twelve more root servers ...]
;; Received 525 bytes from 45.90.28.181#53(45.90.28.181) in 16 ms

com.			172800	IN	NS	i.gtld-servers.net.
[... twelve more gTLD servers ...]
com.			86400	IN	DS	19718 13 2 8ACBB0CD28F41250A80A491389424D341522D946B0DA0C0291F2D3D771D7805A
;; Received 1200 bytes from 192.33.4.12#53(c.root-servers.net) in 12 ms

pinglabz.com.		172800	IN	NS	nsc1.squarespacedns.com.
pinglabz.com.		172800	IN	NS	nsc2.squarespacedns.com.
pinglabz.com.		172800	IN	NS	nsc3.squarespacedns.com.
pinglabz.com.		172800	IN	NS	nsc4.squarespacedns.com.
;; Received 553 bytes from 192.55.83.30#53(m.gtld-servers.net) in 16 ms

pinglabz.com.		14400	IN	A	178.128.137.126
;; Received 90 bytes from 216.239.32.108#53(nsc1.squarespacedns.com) in 40 ms
```

Three referrals and one answer: root to `com`, `com` to the domain's nameservers, then the answer from an authority. When a domain resolves for some people and not others, `+trace` is the tool that finds the broken referral, because it shows you which step stops returning useful data.

One thing to know: `+trace` output on a dual-stack host is noisy if IPv6 is not actually routed. Real capture from this VM:

```
;; UDP setup with 2001:500:2d::d#53(2001:500:2d::d) for pinglabz.com failed: network unreachable.
;; no servers could be reached
```

`dig` tried a root server over IPv6, the host has no IPv6 route, it moved on to an IPv4 server and continued. Add `-4` to keep the output clean. You can also do a single referral manually, which is sometimes more useful than the whole trace:

```
j@llmbits:~$ dig +norecurse @a.root-servers.net com. NS +noall +authority
com.			172800	IN	NS	l.gtld-servers.net.
com.			172800	IN	NS	j.gtld-servers.net.
com.			172800	IN	NS	h.gtld-servers.net.
[...]
```

## DNSSEC from the client side

`+dnssec` sets the DO bit and asks for signatures. Against a signed zone through a validating resolver you get RRSIG records and, more importantly, the `ad` flag:

```
j@llmbits:~$ dig @9.9.9.9 cloudflare.com A +dnssec +noall +answer +comments
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 16053
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
;; ANSWER SECTION:
cloudflare.com.		19	IN	A	104.16.132.229
cloudflare.com.		19	IN	A	104.16.133.229
cloudflare.com.		19	IN	RRSIG	A 13 2 300 20260820145642 20260818125642 34505 cloudflare.com. tBhgro/bZiVA3aXQHdOC2yjoznyhDe0Hh+hnZFeYmZbeeP9b3nL/6UoB s4tc0BCHovIxxx1ZRJLY4Pu0NiG0rQ==
```

`ad` in the flags means the resolver validated the chain. `do` in the EDNS flags means you asked for it. Without `ad`, either the zone is unsigned or the resolver is not validating, and you cannot tell which from this response alone.

When validation fails, you get SERVFAIL and no data at all. The Extended DNS Error tells you why, which is a genuine improvement over the years when SERVFAIL meant "something, somewhere":

```
j@llmbits:~$ dig @9.9.9.9 dnssec-failed.org A +noall +comments
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 21906
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
; EDE: 7 (Signature Expired)
```

That is a validating resolver refusing to hand you an answer it cannot prove, and telling you the signature expired. If a domain suddenly goes SERVFAIL everywhere at once and works when you query its authoritative servers directly, an expired RRSIG is the first thing to check.

## Zone transfers, and why yours should fail

`dig axfr` asks for the entire zone. On a correctly configured server, from an address that is not a listed secondary, this must not work:

```
j@llmbits:~$ dig @10.77.3.10 axfr pinglabz.lab

; <<>> DiG 9.20.26-1~deb13u1-Debian <<>> @10.77.3.10 axfr pinglabz.lab
;; global options: +cmd
; Transfer failed.
```

"Transfer failed" is the correct, healthy result. The lab server returns REFUSED for AXFR from any client. If you run this against your own authoritative servers from a random host and get the whole zone back, you have just handed an attacker your complete internal naming scheme, and that is a finding to fix today. For what an attacker does with an open AXFR and the rest of the offensive DNS toolkit, see the [DNS enumeration cluster](https://www.pinglabz.com/dns-enumeration/). This article stays on the defensive side of that line.

## Batch mode and scripting

`-f` reads queries from a file, one per line, and reuses the same options for all of them:

```
j@llmbits:~$ cat /tmp/dig-batch.txt
www.pinglabz.lab A
pinglabz.lab MX
srv1.pinglabz.lab A

j@llmbits:~$ dig @10.77.3.10 -f /tmp/dig-batch.txt +noall +answer
www.pinglabz.lab.	3600	IN	A	10.77.2.10
pinglabz.lab.		3600	IN	MX	10 mail.pinglabz.lab.
pinglabz.lab.		3600	IN	MX	20 mail2.pinglabz.lab.
srv1.pinglabz.lab.	3600	IN	A	10.77.3.10
```

For anything more shaped than that, loop with `+short`. Note the last line: an NXDOMAIN produces an empty string rather than an error, which is exactly what you want in a report:

```
j@llmbits:~$ while read n; do printf '%-24s %s\n' "$n" "$(dig @10.77.3.10 +short $n | head -1)"; done < /tmp/names.txt
www.pinglabz.lab         10.77.2.10
srv1.pinglabz.lab        10.77.3.10
mail.pinglabz.lab        10.77.3.20
nothere.pinglabz.lab     
```

One caveat that bites people writing monitoring checks: `dig` returns exit status 0 for NXDOMAIN, because the query itself succeeded. If you need a pass/fail exit code, test whether the output is empty, or use `host`, which does set a non-zero status on NXDOMAIN. That difference is covered in [the host guide](https://www.pinglabz.com/host-command-linux/).

## A troubleshooting order that works

**1\. Ask your resolver**`dig name +noall +answer +comments`. Note the status and which server answered. 

**2\. Ask a known-good resolver**`dig @9.9.9.9 name`. If this works and step 1 does not, the zone is fine and your resolver path is broken. 

**3\. Find the authority**`dig NS domain +short`, then query each one directly. Authoritative servers that disagree is a real and common fault. 

**4\. Walk the delegation**`dig +trace -4 name`. Shows which referral step stops producing useful data. 

**5\. Test transport**`dig +tcp` and `dig +noedns`. Size-dependent failures are almost always a firewall or a middlebox. 

**6\. Watch the wire**`tcpdump -ni eth0 port 53`. Confirms whether the query left the host and whether anything came back. 

## FAQ

### Why does dig give a different answer from ping?

Because they use different resolution paths. `dig` speaks DNS directly to a nameserver. `ping` goes through the C library resolver, which consults `/etc/nsswitch.conf` first, so `/etc/hosts`, mDNS and a local caching stub can all answer before DNS is ever consulted. This is the single most common source of "but dig says it is right" confusion, and [how Linux resolves names](https://www.pinglabz.com/linux-dns-resolution/) covers the full path.

### What does the aa flag actually tell me?

That the answer came from a server that holds the zone, not from a cache. Combined with a TTL that matches the configured value rather than counting down, it is how you confirm you are talking to an authority. Its absence is not a problem in itself; almost every answer from a public resolver lacks it.

### Is dig ANY still useful?

Against your own authoritative server, yes: it is a fast way to see everything at one name, as the captures above show. Against public resolvers, mostly no. Many now return a minimal or synthesized response to ANY rather than the full record set, because ANY was heavily used for DNS amplification attacks. If you need everything from a real domain, query each type you care about.

### How do I stop dig from using my search domain?

`dig` does not apply the search list by default, which is why `dig www` often fails while `ping www` works. Use `+search` to opt in, or type the fully qualified name with a trailing dot to be unambiguous.

### What is the \[1au\] in tcpdump output?

One additional record in the query, which is the EDNS0 OPT pseudo-record advertising your buffer size. Query it with `+noedns` and that `[1au]` disappears from the capture. It is a quick way to confirm at the packet level whether EDNS0 is in play.

### Which package provides dig?

`dnsutils` on Debian and Ubuntu, `bind-utils` on RHEL, Rocky and Fedora. The same package ships `host` and `nslookup`, so installing one gets you all three.

## Key takeaways

- Read the status line first. `NXDOMAIN`, `NOERROR` with zero answers, `SERVFAIL` and `REFUSED` are four different problems with four different owners.
- `@server` is the most valuable thing `dig` does, because it separates "the zone is wrong" from "my resolver path is wrong".
- `+noall +answer` for daily use, `+short` for scripts, no options at all when something is broken.
- The `aa` flag and a TTL that does not count down mean you reached an authority rather than a cache.
- DNS falls back from UDP to TCP on large responses. A firewall permitting only UDP 53 produces intermittent, size-dependent failures.
- `+trace` walks the delegation from the root and shows exactly which referral breaks. Add `-4` on hosts without IPv6 routing.
- `dig` exits 0 on NXDOMAIN. For pass/fail scripting, test for empty output or use `host`.
- A successful `dig axfr` against your own authoritative server from an arbitrary host is a finding, not a feature.

Next in this cluster: [host](https://www.pinglabz.com/host-command-linux/) for one-line answers, [nslookup](https://www.pinglabz.com/nslookup-linux/) for the cross-platform habit, and [how Linux resolves names](https://www.pinglabz.com/linux-dns-resolution/) for the path that `dig` deliberately skips. All of them, plus the rest of the toolset, are indexed on the [Linux networking commands](https://www.pinglabz.com/linux-networking-commands/) pillar.