Basic Queries
The shape is . With no type, dig asks for A records.
| Command | What it does |
|---|---|
| IPv4 address (A record) | |
| IPv6 address | |
| Mail servers, with priority | |
| TXT records: SPF, DKIM, domain verification strings | |
| Authoritative name servers for the zone | |
| Where an alias points | |
| Zone serial number and refresh timers | |
| Which certificate authorities may issue for the domain | |
| Service record: target host and port for a service | |
| HTTPS/SVCB record: the ALPN and ECH hints browsers read (BIND 9.18+) | |
| DMARC policy; SPF lives in the apex TXT record instead | |
| Several lookups in one call | |
| Type as a flag; same as |
All Records
There is no working "give me everything" query any more.
| Command | What it does |
|---|---|
| The old catch-all; Cloudflare and others reply with one RFC 8482 HINFO record | |
| The practical replacement: repeat name and type per query | |
| Full zone transfer; refused unless your IP is an allowed secondary | |
| Incremental transfer from a zone serial |
Loop the types you actually care about:
for t in A AAAA MX TXT NS SOA CAA; do dig +noall +answer example.com "$t"; doneShort Answers
| Command | What it does |
|---|---|
| Just the address, one per line | |
| Priority and mail server, nothing else | |
| Full answer records with TTLs, none of the header noise | |
| Answer plus which server gave it | |
| One field per line; readable for SOA and DNSKEY |
An aliased name prints its whole CNAME chain under , one line per step:
dig +short www.example.com | tail -n1 # only the final IP addressQuerying a Specific Server
Prefix any query with to skip your normal resolver.
| Command | What it does |
|---|---|
| Ask Google's public resolver instead of your own | |
| Ask Cloudflare's | |
| Ask the domain's own name server; no cache in the way | |
| Non-standard port, for a local test resolver | |
| SOA serial from every authoritative server; spots a lagging secondary |
Checking whether a DNS change has propagated is a two-query job:
dig +short example.com @ns1.example.com # what the zone actually says
dig +short example.com @8.8.8.8 # what the world still sees cachedReverse Lookups
takes a plain IP and builds the PTR query for you, octet reversal included.
| Command | What it does |
|---|---|
| Hostname for an IPv4 address (PTR record) | |
| Just the hostname | |
| IPv6 reverse; dig writes the nibble name for you |
An empty answer is common here: many addresses simply have no PTR record, and that is not an error.
Tracing and Debugging
| Command | What it does |
|---|---|
| Follow the delegation from the root servers down, past every cache | |
| Same trace without the DNSSEC record clutter | |
| Include signatures; a validated answer sets the flag | |
| Force TCP; tests truncation and firewalls that only pass UDP | |
| Fail fast in scripts: 2 second timeout, one attempt | |
| Only answer from cache; shows what a resolver already holds | |
| Query over IPv4 only ( for IPv6 only) | |
| DNS over HTTPS ( for DNS over TLS; BIND 9.18+) |
Reading the Output
A default dig response, trimmed:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 23918
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; QUESTION SECTION:
;example.com. IN A
;; ANSWER SECTION:
example.com. 300 IN A 203.0.113.10
;; Query time: 24 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)| Field | Meaning |
|---|---|
| Query worked. : name does not exist. : resolver failure, often DNSSEC. : server will not answer you | |
| Answer, recursion desired, recursion available. means authoritative, means DNSSEC-validated | |
| Record count in the answer section; with NOERROR means the name exists but not this record type | |
| TTL in seconds; counts down while the answer sits in a cache | |
| What was asked, echoed back | |
| Who answered; is the local systemd-resolved stub, not the real upstream | |
| A 0-1 ms answer almost always came from cache |
Options
| Option | What it does |
|---|---|
| Batch mode: run one query per line of the file | |
| Apply the search domains from resolv.conf (off by default, unlike ssh and curl) | |
| Print the outgoing query as well as the answer | |
| Drop the version banner line | |
| Drop the query time / server footer | |
| Structured output for scripts (BIND 9.16+) | |
| Ignore for this run |
Batch mode pairs naturally with the short output flags:
dig -f domains.txt +noall +answerOptions you always want can live in , one line, same syntax:
+noall +answerInstalling dig
means the BIND utilities are missing, not that DNS is broken. No distro ships a package called .
| Command | Where |
|---|---|
| Debian, Ubuntu (pulls in ) | |
| RHEL, Fedora, Rocky, Alma | |
| Arch; was merged into | |
| Alpine, and most Alpine-based containers | |
| openSUSE | |
| macOS, when you want a newer dig than the system one | |
| Windows, native install |
dig on Windows
cmd and PowerShell have no dig. The built-ins cover most lookups, and WSL gives you the real thing.
| Command | What it does |
|---|---|
| Built-in; the closest thing to | |
| Record type plus a specific server | |
| PowerShell; more record types, cleaner output | |
| PowerShell against a specific server | |
| Real dig through WSL, runnable from any cmd window | |
| Native install of dig via Chocolatey |
ISC stopped building BIND for Windows after 9.16, so standalone dig-for-Windows downloads are old builds. WSL or Chocolatey gets you a current one.
nslookup asks the same servers the same questions, but prints a stripped summary with no TTLs, no flags, and no status line, which is why DNS guides assume dig.
dig on macOS
dig is preinstalled on every macOS release. It reads , which macOS generates from the primary network service only, so dig can miss the per-domain resolvers a VPN adds and disagree with the rest of the system.
| Command | What it does |
|---|---|
| Every resolver macOS is really using, per network service and search domain | |
| The resolver DHCP handed you, to pass back as | |
| Resolve the way macOS apps do, system cache included | |
| Newer dig than the system one, installed as |
Flush the system cache before retesting a record that changed:
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponderGotchas
- prints nothing when the name does not exist. Drop it and read the line before deciding a record is missing.
- ANY is effectively dead: Cloudflare and many other servers answer it with a single RFC 8482 HINFO record. Query each type you care about instead.
- dig asks the DNS server directly and ignores , nsswitch, and mDNS, so dig can resolve a name that still cannot, and the other way round. When SSH is the one failing, see Could not resolve hostname.
- means systemd-resolved answered, possibly from its cache. Retest with before blaming the upstream record.
- A falling TTL plus a 0 ms query time means you are looking at a cached answer, not the zone. or gets the live data.
- and both look like a way to dump a zone, and neither works against a domain you do not run. See All Records for what to do instead.
- dig missing? It lives in the BIND utilities package, never one called dig. See Installing dig above.