Check DNS Answers, Servers and Reverse Lookups with dig
A domain looks fine in the browser but mail is bouncing, so you reach for dig to see exactly what DNS is handing back. This gives you a small set of repeatable dig commands for reading answers, asking a specific resolver, doing reverse lookups and narrowing down a failure. The examples use BIND 9 dig from Ubuntu package bind9-dnsutils 1:9.18.39-0ubuntu0.24.04.7.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about fifteen minutes. You need a shell and network access to a DNS server. These examples only make DNS queries and print output to the terminal: nothing here changes DNS records, resolver configuration or a remote server, and no command needs elevated privileges.
1. Confirm the installed command
Check the binary and its version before relying on an option in a script:
$ command -v dig
/usr/bin/dig
$ dig -v
DiG 9.18.39-0ubuntu0.24.04.7-Ubuntu
The version matters because BIND 9 releases add and retire query options. This guide describes the installed 9.18.39 build. Read the local manual with man dig when a server or a later package has different behaviour.
Checkpoint
Run dig -h. It should print the synopsis and the query options available on your machine. If the command is missing, install the package through your normal system-management process rather than copying a binary from an untrusted source.
2. Make a normal answer query
The simplest form is dig NAME TYPE. The type is optional and defaults to A, which asks for IPv4 address records:
$ dig example.com A
; <<>> DiG 9.18.39-0ubuntu0.24.04.7-Ubuntu <<>> example.com A
;; ANSWER SECTION:
example.com. 192 IN A 104.20.23.154
example.com. 192 IN A 172.66.147.243
;; Query time: ... msec
;; SERVER: ...
Addresses and TTLs vary. The useful sections are the question, answer, authority and additional sections, followed by status and query statistics. A response can be successful even with no answer records:
- NXDOMAIN means the name does not exist.
- NOERROR with an empty answer can mean the requested type is simply absent, not that the domain is broken.
For a script or a quick human check, select only the answer section:
$ dig +noall +answer example.com A
example.com. 192 IN A 104.20.23.154
example.com. 192 IN A 172.66.147.243
+short is even terser and prints only the record data:
$ dig +short example.com A
104.20.23.154
172.66.147.243
Do not parse the formatted default output when +short or +noall +answer gives you the narrower contract you need. DNS answers are not guaranteed to have one record or one stable order.
3. Ask a particular resolver
Your normal resolver comes from /etc/resolv.conf. Put @server before the name when you need to compare it with another resolver:
$ dig @1.1.1.1 +noall +answer example.com NS
example.com. 70399 IN NS hera.ns.cloudflare.com.
example.com. 70399 IN NS elliott.ns.cloudflare.com.
The server name can be a host name or an address. If you are checking a machine's configured resolver, run the same query first without @1.1.1.1, then compare the status, records and TTLs. A different answer does not by itself prove that one server is broken: caches, DNS views, delegation changes and split-horizon configuration can all matter.
Use +tcp when testing TCP explicitly. Ordinary queries use UDP first and retry over TCP when a response is truncated. An AXFR zone transfer always uses TCP according to the manual, but do not attempt a transfer against a zone you do not administer.
4. Perform a reverse lookup
Use -x with an IPv4 or IPv6 address. It builds the matching reverse-DNS name and asks for a PTR record:
$ dig -x 8.8.8.8 +short
dns.google.
A PTR record is an assertion made by the address holder, not proof of identity. It may be missing, generic or unrelated to a service's forward records. To compare both directions, query the returned name for an address and check whether the original address comes back. Forward-confirmed reverse DNS is useful evidence, but it is not authentication.
5. Separate a name, type and transport problem
Make the query explicit while investigating:
$ dig +noall +answer example.com MX
$ dig +noall +answer example.com TXT
$ dig +4 +time=2 +tries=1 +noall +answer example.com A
- MX checks mail exchangers.
- TXT checks text records.
- +4 forces IPv4 transport;
+time=2sets a two-second timeout and+tries=1makes one attempt.
These settings are useful for a bounded diagnostic, but they can turn a slow network into a false failure if copied into general-purpose scripts.
When you need to see the delegation path rather than ask one recursive resolver, use:
$ dig +trace example.com A
Trace mode performs iterative queries starting at the root and prints the servers it follows. It can be slower and produce much more output. The local manual says it also enables DNSSEC-related querying and disables recursion for this operation. Treat a trace as a diagnostic conversation with many DNS servers, not as a single equivalent of the normal lookup.
6. Control hidden local defaults
Two easy things make a copied command behave differently from what you can see on the line.
- dig reads ~/.digrc automatically and applies query options from it. Check that file when output or flags seem inexplicable. Use
-rto skip it for a clean diagnostic. - The search list is off by default in this BIND 9 build. Do not assume an unqualified name will be expanded from
/etc/resolv.conf.+searchenables that behaviour and+nosearchdisables it; a trailing dot, as inhost.example., is visibly absolute and avoids an accidental search-list lookup.
$ dig -r +noall +answer example.com A
Warning
The manual supports TSIG keys through -k keyfile. Avoid -y in shared terminals, shell history and process listings because it places the secret on the command line. Keep key files readable only by the account that needs them, and do not paste their contents into a guide or ticket.
7. Read the exit status correctly
Check the status immediately after the query:
$ dig +short example.com A >/tmp/example-addresses
$ status=$?
$ printf 'dig exit status: %s\n' "$status"
dig exit status: 0
The installed manual documents these exit codes:
- 0 for a DNS response, including
NXDOMAIN. - 1 for a usage error.
- 8 when a batch file cannot be opened.
- 9 for no reply.
- 10 for an internal error.
A zero status therefore means that a DNS response arrived, nothing more: not that the name exists, and not that it contains the record type you wanted.
The temporary file above is optional and contains only the selected addresses. Remove it when you no longer need it with rm -- /tmp/example-addresses. That removal is safe for this example, but never substitute a broad path for the explicit file name.
Done means
- You confirmed the installed BIND 9 dig version and checked its local help.
- You can choose between full output,
+noall +answerand+short. - You can compare the configured resolver with an explicit
@server. - You know that
-xperforms reverse DNS and that a PTR record is not authentication. - You can distinguish a DNS response from a successful answer by checking both status and content.
- You checked
~/.digrc, search-list behaviour and credential handling before trusting a copied command.