Linux dig and nslookup Commands
last modified October 23, 2026
The dig and nslookup commands query the Domain
Name System (DNS). They show which addresses a name resolves to, which
servers handle mail for a domain, which name servers are authoritative for
it, and much more. dig (domain information groper) shows the
DNS response in detail and is the tool of choice for troubleshooting;
nslookup is older, simpler, and also available on Windows.
Both come from the BIND project; on Debian and Ubuntu they are in the
bind9-dnsutils package (dnsutils on older
releases), on Fedora in bind-utils. The examples were run on
Ubuntu 22.04 with BIND 9.18, which uses the local systemd-resolved stub
resolver at 127.0.0.53. The answers come from the live DNS, so the
addresses and TTL values will differ when you run the commands.
A basic query
Without options, dig asks for the A record (the IPv4
address) of a name.
dig example.com
The output mirrors the DNS message. The header shows the
status (NOERROR means success) and the flags:
qr marks a response, rd says that we asked for
recursion, and ra that the server offers it. The question
section repeats what we asked; the answer section holds the records. Each
record has five fields: name, TTL in seconds, class (IN for
Internet), type, and data. Here, example.com has two IPv4
addresses. The last lines show the query time and the server that answered,
the local resolver.
$ dig example.com ; <<>> DiG 9.18.39-0ubuntu0.22.04.7-Ubuntu <<>> example.com ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62983 ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 65494 ;; QUESTION SECTION: ;example.com. IN A ;; ANSWER SECTION: example.com. 144 IN A 104.20.23.154 example.com. 144 IN A 172.66.147.243 ;; Query time: 0 msec ;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP) ;; WHEN: Fri Oct 23 21:44:15 CEST 2026 ;; MSG SIZE rcvd: 72
Short output
The +short option prints only the data of the answer.
dig +short example.com dig +short zetcode.com
Options that start with + are query options, specific to
dig. They can be placed anywhere on the command line. The
order of multiple records may change from query to query; resolvers rotate
them to spread the load.
$ dig +short example.com 104.20.23.154 172.66.147.243 $ dig +short zetcode.com 164.92.191.90
Record types
The record type follows the name. The most common types are summarized in the following table.
| Type | Content |
|---|---|
A | IPv4 address |
AAAA | IPv6 address |
CNAME | Alias: the canonical name of the host |
MX | Mail server with a preference number |
NS | Authoritative name server of the zone |
TXT | Free text: SPF, domain verification tokens |
SOA | Start of authority: zone parameters |
PTR | Name for an address (reverse lookup) |
SRV | Host and port of a service |
CAA | Certificate authorities allowed to issue certificates |
dig +short example.com AAAA dig +short gnu.org MX dig +short example.com NS dig +short example.com TXT dig +short example.com SOA
The mail server of gnu.org is eggs.gnu.org, with
preference 10; with several MX records, the lowest number is tried first.
example.com is served by Cloudflare name servers. Its SPF
record v=spf1 -all says that no server may send mail for the
domain. The SOA record lists the primary name server, the mailbox of the
administrator (dns.cloudflare.com stands for
dns@cloudflare.com), the serial number, and timers.
$ dig +short example.com AAAA 2606:4700:10::6814:179a 2606:4700:10::ac42:93f3 $ dig +short gnu.org MX 10 eggs.gnu.org. $ dig +short example.com NS elliott.ns.cloudflare.com. hera.ns.cloudflare.com. $ dig +short example.com TXT "_k2n1y4vw3qtb4skdx9e7dxt97qrmmq9" "v=spf1 -all" $ dig +short example.com SOA elliott.ns.cloudflare.com. dns.cloudflare.com. 2418004112 10000 2400 604800 1800
Controlling the output
The +noall option turns off all output sections, and other
options turn the wanted ones back on. +noall +answer is the
most useful combination: full records without the rest.
dig +noall +answer gnu.org MX dig +noall +answer www.kernel.org
Unlike +short, this shows names, TTLs, and types. The second
query shows a CNAME chain: www.kernel.org is an alias for a
name at the Fastly content delivery network, which has the A record. The
resolver follows the chain and returns all records. A CNAME cannot coexist
with other records of the same name, so the apex of a domain, such as
kernel.org, never has one.
$ dig +noall +answer gnu.org MX gnu.org. 235 IN MX 10 eggs.gnu.org. $ dig +noall +answer www.kernel.org www.kernel.org. 60 IN CNAME dualstack.m.sni.global.fastly.net. dualstack.m.sni.global.fastly.net. 25 IN A 199.232.17.55
Multiline output
The +multiline option prints long records such as SOA over
several lines, with comments.
dig +noall +answer +multiline example.com SOA
The serial number changes with every update of the zone. The refresh, retry, and expire timers control secondary servers that copy the zone. The last value is the TTL for negative answers: a resolver caches the fact that a name does not exist for 30 minutes.
$ dig +noall +answer +multiline example.com SOA example.com. 1542 IN SOA elliott.ns.cloudflare.com. dns.cloudflare.com. ( 2418004112 ; serial 10000 ; refresh (2 hours 46 minutes 40 seconds) 2400 ; retry (40 minutes) 604800 ; expire (1 week) 1800 ; minimum (30 minutes) )
Querying a specific server
A server name or address prefixed with @ sends the query to
that server instead of the system resolver.
dig @1.1.1.1 example.com +noall +answer +stats dig @8.8.8.8 +short gnu.org
1.1.1.1 is Cloudflare's public resolver and 8.8.8.8 Google's. Comparing
answers from several resolvers helps find out whether a problem lies with
the local resolver, for example a stale cache, or with the domain itself.
The +stats option adds the query time and the server.
$ dig @1.1.1.1 example.com +noall +answer +stats example.com. 266 IN A 104.20.23.154 example.com. 266 IN A 172.66.147.243 ;; Query time: 4 msec ;; SERVER: 1.1.1.1#53(1.1.1.1) (UDP) ;; WHEN: Fri Oct 23 21:44:15 CEST 2026 ;; MSG SIZE rcvd: 72 $ dig @8.8.8.8 +short gnu.org 209.51.188.116
Asking an authoritative server
Resolvers such as 1.1.1.1 look names up on behalf of clients and cache the results. Authoritative servers hold the zone data. We can find them with an NS query and ask them directly.
dig +short example.com NS dig @elliott.ns.cloudflare.com example.com
The response has the aa (authoritative answer) flag and lacks
ra: authoritative servers do not resolve other names for us,
which the warning points out. The TTL is the full value configured in the
zone, 300 seconds. Asking the authoritative server is how we verify a DNS
change right after making it, before caches expire.
$ dig +short example.com NS elliott.ns.cloudflare.com. hera.ns.cloudflare.com. $ dig @elliott.ns.cloudflare.com example.com ; <<>> DiG 9.18.39-0ubuntu0.22.04.7-Ubuntu <<>> @elliott.ns.cloudflare.com example.com ; (6 servers found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 27749 ;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1 ;; WARNING: recursion requested but not available ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 1232 ;; QUESTION SECTION: ;example.com. IN A ;; ANSWER SECTION: example.com. 300 IN A 172.66.147.243 example.com. 300 IN A 104.20.23.154 ;; Query time: 3 msec ;; SERVER: 108.162.195.228#53(elliott.ns.cloudflare.com) (UDP) ;; WHEN: Fri Oct 23 21:44:15 CEST 2026 ;; MSG SIZE rcvd: 72
TTL and caching
The TTL in an answer from a resolver counts down while the record sits in its cache.
dig +noall +answer gnu.org sleep 5 dig +noall +answer gnu.org dig @8.8.8.8 +noall +answer gnu.org
Five seconds later, the local resolver returns the same record with a TTL five seconds lower. Google's resolver has its own cache, with its own countdown. When a record changes, clients may see the old value until the TTL runs out in every cache on the way; this is why administrators lower the TTL ahead of a planned change.
$ dig +noall +answer gnu.org gnu.org. 175 IN A 209.51.188.116 $ sleep 5 $ dig +noall +answer gnu.org gnu.org. 170 IN A 209.51.188.116 $ dig @8.8.8.8 +noall +answer gnu.org gnu.org. 266 IN A 209.51.188.116
Reverse lookups
The -x option looks up the name of an IP address. It builds
the PTR query for the special in-addr.arpa domain, with the
address bytes reversed.
dig -x 8.8.8.8 +short dig -x 1.1.1.1 +noall +answer
Reverse records are maintained by the owner of the address block, not of the domain, so many addresses have no PTR record, or one with a generic name from the hosting provider. Mail servers often check them.
$ dig -x 8.8.8.8 +short dns.google. $ dig -x 1.1.1.1 +noall +answer 1.1.1.1.in-addr.arpa. 1480 IN PTR one.one.one.one.
Names that do not exist
The status field in the header tells why there is no
answer.
dig no-such-host.gnu.org echo $?
NXDOMAIN means the name does not exist. The authority section
holds the SOA record of the zone; its last field sets how long resolvers
may cache this negative answer. Note that dig exits with
status 0: it got an answer, even though the answer is negative. In scripts,
check the status or the output, not the exit code.
$ dig no-such-host.gnu.org ; <<>> DiG 9.18.39-0ubuntu0.22.04.7-Ubuntu <<>> no-such-host.gnu.org ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 45355 ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 65494 ;; QUESTION SECTION: ;no-such-host.gnu.org. IN A ;; AUTHORITY SECTION: gnu.org. 286 IN SOA ns1.gnu.org. hostmaster.gnu.org. 2026071502 3600 120 1209600 3600 ;; Query time: 56 msec ;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP) ;; WHEN: Fri Oct 23 21:44:21 CEST 2026 ;; MSG SIZE rcvd: 100 $ echo $? 0
Names without the requested record
A name can exist but have no records of the requested type.
dig +noall +comments +answer +authority www.gnu.org MX
The status is NOERROR, but the answer section is empty
(ANSWER: 0). This is called a NODATA response:
www.gnu.org exists, it just has no MX record. Looking only at
+short output, NODATA and NXDOMAIN look the same: empty. The
+comments option shows the header lines.
$ dig +noall +comments +answer +authority www.gnu.org MX ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 14913 ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 65494 ;; AUTHORITY SECTION: gnu.org. 286 IN SOA ns1.gnu.org. hostmaster.gnu.org. 2026071502 3600 120 1209600 3600
Unreachable servers and timeouts
The +time option sets the timeout for one attempt in seconds
(default 5), and +tries the number of attempts (default
3).
dig @192.0.2.1 example.com +time=1 +tries=2 echo $?
Nothing listens at 192.0.2.1, an address reserved for documentation. After
two attempts, dig gives up and exits with status 9 (no reply
from server). Status 0 means a response arrived, 1 a usage error, 8 a
problem with the batch file, and 10 an internal error.
$ dig @192.0.2.1 example.com +time=1 +tries=2 ;; communications error to 192.0.2.1#53: timed out ;; communications error to 192.0.2.1#53: timed out ; <<>> DiG 9.18.39-0ubuntu0.22.04.7-Ubuntu <<>> @192.0.2.1 example.com +time=1 +tries=2 ; (1 server found) ;; global options: +cmd ;; no servers could be reached $ echo $? 9
Tracing the resolution
The +trace option makes dig resolve the name
itself, step by step, starting from the root servers, instead of asking a
resolver.
dig -4 +trace +nodnssec example.com
The first step gets the list of root servers from the local resolver. A
root server refers dig to the servers of the
com top-level domain; one of those refers it to the Cloudflare
name servers of example.com, which give the final answer.
+nodnssec hides the signature records, and -4
uses only IPv4. Without -4, on a host without IPv6
connectivity, the output is mixed with network unreachable
errors for the IPv6 addresses of the servers. A trace shows where a
delegation is broken, for example when the parent zone lists name servers
that do not answer.
$ dig -4 +trace +nodnssec example.com ; <<>> DiG 9.18.39-0ubuntu0.22.04.7-Ubuntu <<>> -4 +trace +nodnssec example.com ;; global options: +cmd . 7165 IN NS j.root-servers.net. . 7165 IN NS f.root-servers.net. . 7165 IN NS l.root-servers.net. . 7165 IN NS c.root-servers.net. . 7165 IN NS b.root-servers.net. . 7165 IN NS d.root-servers.net. . 7165 IN NS g.root-servers.net. . 7165 IN NS i.root-servers.net. . 7165 IN NS k.root-servers.net. . 7165 IN NS e.root-servers.net. . 7165 IN NS m.root-servers.net. . 7165 IN NS h.root-servers.net. . 7165 IN NS a.root-servers.net. ;; Received 239 bytes from 127.0.0.53#53(127.0.0.53) in 0 ms com. 172800 IN NS j.gtld-servers.net. com. 172800 IN NS b.gtld-servers.net. com. 172800 IN NS l.gtld-servers.net. com. 172800 IN NS f.gtld-servers.net. com. 172800 IN NS k.gtld-servers.net. com. 172800 IN NS a.gtld-servers.net. com. 172800 IN NS d.gtld-servers.net. com. 172800 IN NS h.gtld-servers.net. com. 172800 IN NS e.gtld-servers.net. com. 172800 IN NS g.gtld-servers.net. com. 172800 IN NS i.gtld-servers.net. com. 172800 IN NS c.gtld-servers.net. com. 172800 IN NS m.gtld-servers.net. ;; Received 864 bytes from 192.33.4.12#53(c.root-servers.net) in 5 ms example.com. 172800 IN NS hera.ns.cloudflare.com. example.com. 172800 IN NS elliott.ns.cloudflare.com. ;; Received 359 bytes from 192.35.51.30#53(f.gtld-servers.net) in 36 ms example.com. 300 IN A 104.20.23.154 example.com. 300 IN A 172.66.147.243 ;; Received 72 bytes from 108.162.195.228#53(elliott.ns.cloudflare.com) in 6 ms
DNSSEC
DNSSEC signs DNS records, so a resolver can verify that the answers are
genuine. The +dnssec option requests the signatures.
dig @1.1.1.1 example.com +dnssec +noall +comments | grep flags dig @1.1.1.1 example.com +dnssec +noall +answer
The ad (authenticated data) flag means that the resolver
validated the signatures. The do flag in the EDNS line is the
"DNSSEC OK" bit that dig sent. The RRSIG record is the
signature of the A records, with algorithm 13 (ECDSA P-256 with SHA-256),
its validity period, and the key tag.
$ dig @1.1.1.1 example.com +dnssec +noall +comments | grep flags ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1 ; EDNS: version: 0, flags: do; udp: 1232 $ dig @1.1.1.1 example.com +dnssec +noall +answer example.com. 258 IN A 104.20.23.154 example.com. 258 IN A 172.66.147.243 example.com. 258 IN RRSIG A 13 2 300 20261024204340 20261022184340 34505 example.com. 3EUyS80evtUQ5jWQiWZKzh4lE6EX6Pbz7awuwIcoHeiKN3ETWapq1+40 JzQyNjKCjrXniCDnoIARZufkrQw6vA==
Querying many names
The -f option reads queries from a file, one per line.
cat domains.txt dig -f domains.txt +noall +answer
Each line may contain a full query, including a type and options, such as
gnu.org MX +short. The options on the command line apply to
all queries.
$ cat domains.txt example.com gnu.org kernel.org $ dig -f domains.txt +noall +answer example.com. 136 IN A 104.20.23.154 example.com. 136 IN A 172.66.147.243 gnu.org. 257 IN A 209.51.188.116 kernel.org. 265 IN A 172.105.4.254
Using dig in scripts
+short output is easy to process in shell scripts. The
following script prints the preferred mail server of each domain.
cat check-mx.sh bash check-mx.sh gnu.org example.com no-such-domain-xyz.com
example.com has a null MX record, 0 ., which
says that the domain does not accept mail at all (RFC 7505). For the
nonexistent domain, the output is empty. With several MX records,
sort -n puts the lowest preference first.
$ cat check-mx.sh
#!/bin/bash
for domain in "$@"; do
mx=$(dig +short "$domain" MX)
if [ -z "$mx" ]; then
echo "$domain: no MX records"
elif [ "$mx" = "0 ." ]; then
echo "$domain: does not accept mail (null MX)"
else
echo "$domain: $(echo "$mx" | sort -n | head -1 | cut -d' ' -f2)"
fi
done
$ bash check-mx.sh gnu.org example.com no-such-domain-xyz.com
gnu.org: eggs.gnu.org.
example.com: does not accept mail (null MX)
no-such-domain-xyz.com: no MX records
The ANY query
The ANY type used to return all records of a name. It was
abused for amplification attacks, and RFC 8482 allows servers to refuse
it.
dig @1.1.1.1 +noall +comments example.com ANY
Cloudflare's resolver answers NOTIMP (not implemented), with
an extended error code saying so. Other servers return a single record or
a synthetic HINFO record. To see the records of a name, query the types
one by one.
$ dig @1.1.1.1 +noall +comments example.com ANY ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOTIMP, id: 62074 ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 1232 ; EDE: 21 (Not Supported)
dig and /etc/hosts
dig talks to DNS servers directly. It does not read
/etc/hosts or use the other sources configured in
/etc/nsswitch.conf, which ordinary programs use through the
system library. The getent command shows what those programs
see. This example was run in a Debian container, where the name
myapp was added to /etc/hosts.
grep myapp /etc/hosts getent hosts myapp dig +short myapp getent hosts example.com
getent finds myapp, dig does not.
When a browser and dig disagree, check
/etc/hosts first. getent hosts prefers IPv6
addresses; getent ahosts lists all of them.
$ grep myapp /etc/hosts 10.0.0.5 myapp $ getent hosts myapp 10.0.0.5 myapp $ dig +short myapp $ getent hosts example.com 2606:4700:10::ac42:93f3 example.com 2606:4700:10::6814:179a example.com
The nslookup command
nslookup prints the answers in a simpler, more readable
form.
nslookup example.com
The first two lines show the server used. Non-authoritative
answer means that the answer comes from a resolver's cache, not from
an authoritative server. Without a type, nslookup asks for
both A and AAAA records.
$ nslookup example.com Server: 127.0.0.53 Address: 127.0.0.53#53 Non-authoritative answer: Name: example.com Address: 104.20.23.154 Name: example.com Address: 172.66.147.243 Name: example.com Address: 2606:4700:10::ac42:93f3 Name: example.com Address: 2606:4700:10::6814:179a
Record types, servers, and reverse lookups
The -type option selects the record type, and a second
argument the server.
nslookup -type=mx gnu.org nslookup example.com 1.1.1.1 nslookup 8.8.8.8
An IP address as the argument makes nslookup do a reverse
lookup automatically. The empty Authoritative answers can be found
from heading is printed by this version even when there is nothing to
list under it.
$ nslookup -type=mx gnu.org Server: 127.0.0.53 Address: 127.0.0.53#53 Non-authoritative answer: gnu.org mail exchanger = 10 eggs.gnu.org. Authoritative answers can be found from: $ nslookup example.com 1.1.1.1 Server: 1.1.1.1 Address: 1.1.1.1#53 Non-authoritative answer: Name: example.com Address: 104.20.23.154 Name: example.com Address: 172.66.147.243 Name: example.com Address: 2606:4700:10::ac42:93f3 Name: example.com Address: 2606:4700:10::6814:179a $ nslookup 8.8.8.8 8.8.8.8.in-addr.arpa name = dns.google. Authoritative answers can be found from:
Interactive nslookup
Without arguments, nslookup starts an interactive session
with the > prompt. Settings stay in effect for the
following queries.
nslookup set type=mx gnu.org server 1.1.1.1 debian.org exit
set type=mx applies to all following lookups, and
server switches to another server. debian.org has
three mail servers with the same preference, so mail is spread among them.
$ nslookup > set type=mx > gnu.org Server: 127.0.0.53 Address: 127.0.0.53#53 Non-authoritative answer: gnu.org mail exchanger = 10 eggs.gnu.org. Authoritative answers can be found from: > server 1.1.1.1 Default server: 1.1.1.1 Address: 1.1.1.1#53 > debian.org Server: 1.1.1.1 Address: 1.1.1.1#53 Non-authoritative answer: debian.org mail exchanger = 0 mailly.debian.org. debian.org mail exchanger = 0 muffat.debian.org. debian.org mail exchanger = 0 mitropoulos.debian.org. Authoritative answers can be found from: > exit
The host command
The host command, from the same package, gives the most
compact output.
host example.com host -t mx gnu.org host 8.8.8.8
Without a type, host looks up the A, AAAA, and MX records,
and an IP address triggers a reverse lookup. The -t option
selects the type.
$ host example.com example.com has address 104.20.23.154 example.com has address 172.66.147.243 example.com has IPv6 address 2606:4700:10::6814:179a example.com has IPv6 address 2606:4700:10::ac42:93f3 example.com mail is handled by 0 . $ host -t mx gnu.org gnu.org mail is handled by 10 eggs.gnu.org. $ host 8.8.8.8 8.8.8.8.in-addr.arpa domain name pointer dns.google.
dig, nslookup, or host
- dig: Shows the complete response, including status,
flags, and TTLs. Use it for troubleshooting and in scripts with
+short. - nslookup: Readable output and an interactive mode; available on Windows, so instructions for mixed environments often use it.
- host: One line per record; good for a quick check.
- getent hosts: Shows how the system resolves a name,
including
/etc/hosts.
Source
dig manual page, nslookup manual page
In this article, we have used dig to query record types,
specific and authoritative servers, reverse names, and to trace a
resolution from the root, and we have read status codes, flags, and TTLs.
We have also used nslookup, host, and
getent. See also the
ping and traceroute article.
Author
List all Linux tutorials.