๐ nslookup and dig: the two tools you'll actually use
Two CLI tools, same job, different defaults.
nslookupis the everywhere-default: Windows ships it, macOS and Linux ship it, your jumpbox has it.digis the modern troubleshooter: verbose, scriptable, designed to answer "what did the wire actually carry." Both belong in your hands; the one to use depends on what you're trying to learn.
This page covers what each tool is, how to drive it, and where its defaults will surprise you. The deeper-dive dig pages: dig-along and dig-flags pick up where this one ends. Background on how a query travels the hierarchy is in anatomy-of-a-query.
At a glance#
nslookup | dig | |
|---|---|---|
| Shipped by | Microsoft (Windows), Apple (macOS), Linux distros | ISC (part of BIND) |
| Default behavior on a bare name | Appends search suffix from resolver config | Asks for the bare name as given |
| Default record type | A + AAAA, looked up together | A only |
| Default resolver | OS-configured DNS | OS-configured (/etc/resolv.conf) |
| Interactive mode | Yes (nslookup with no args) | No |
| Output style | Human-friendly, conversational | Structured, section-based, scriptable |
| Best for | Quick "what's this name?" / Windows shops / interactive sessions | Troubleshooting, scripts, DNSSEC, EDNS, weird record types |
| Reference | [Microsoft Learn: nslookup][ms-nslookup] | [ISC BIND 9: dig manpage][isc-dig] |
[ms-nslookup]: https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/nslookup [isc-dig]: https://bind9.readthedocs.io/en/latest/manpages.html#dig-dns-lookup-utility
Neither tool is "better." They answer the same question and one is right next to your hand more often than the other.
nslookup: the everywhere default#
Non-interactive#
nslookup isitdns.net
nslookup isitdns.net 1.1.1.1
nslookup -type=MX isitdns.net 1.1.1.1
nslookup -type=TXT isitdns.net 1.1.1.1Interactive#
nslookup
> server 1.1.1.1
> set type=AAAA
> isitdns.net
> set debug
> set d2
> isitdns.net
> exitset debug shows the question, answer, authority, and additional sections plus each record's TTL. set d2 adds lower-level detail: on Windows it dumps the outgoing query packets too; BIND's nslookup prints internal library tracing instead. In non-interactive mode you get the same depth with dig; nslookup interactive mode is most useful on Windows where dig may not be installed.
The search-suffix quirk: the one to know#
When you type:
nslookup webmailnslookup will quietly append the search suffix (or "DNS suffix" in Windows terms) from your resolver configuration before issuing the query. If your Mac's /etc/resolv.conf has search corp.example.com or your Windows network adapter has a configured DNS suffix of corp.example.com, the query that actually leaves your machine is:
webmail.corp.example.comYou'll see this in the response: the "Name:" line will show the expanded name, not what you typed. That's fine when you wanted it, and a head-scratcher when you didn't.
How to force the literal name:
nslookup webmail.The trailing dot forces FQDN treatment: no search suffix is appended. A trailing dot is the universal "this is fully qualified, leave it alone" signal across DNS tools. It works in nslookup, in zone files, and in browser URL bars on most platforms.
๐ Why this matters. A query for
webmailon a corporate network may return a real answer ("oh, it'swebmail.corp.example.com, here's its IP") even though that's not what you intended. Always trailing-dot when you mean a bare name during DNS troubleshooting.
"Non-authoritative answer:": what it means#
nslookup prints Non-authoritative answer: above any response whose aa (Authoritative Answer) bit is 0. In practice that is every answer relayed by a recursive resolver, whether it was a cache hit or the resolver walked to the authoritative server fresh for it. The label does not mean "this came from cache"; it means "the server that answered me does not own this zone." It's information, not an error.
The only way to make the label go away is to query a server that is authoritative for the name, which answers with aa=1. A recursive resolver never sets the Authoritative Answer bit, even on a cache miss; that bit is reserved for servers that own the zone. You can confirm this in dig output by checking the flags line; nslookup's normal output does not surface the aa bit (Windows nslookup will show header flags under set debug; BIND's will not).
Common nslookup recipes#
nslookup isitdns.net 1.1.1.1Server: 1.1.1.1
Address: 1.1.1.1#53
Non-authoritative answer:
Name: isitdns.net
Address: 104.21.56.211
Name: isitdns.net
Address: 172.67.155.242
Name: isitdns.net
Address: 2606:4700:3032::6815:38d3
Name: isitdns.net
Address: 2606:4700:3036::ac43:9bf2Note the IPv6 lines: with no -type given, modern nslookup (both the BIND and Windows versions) looks up A and AAAA in one shot and prints both. dig with no type asks only for A.
nslookup -type=MX cloudflare.com 1.1.1.1Server: 1.1.1.1
Address: 1.1.1.1#53
Non-authoritative answer:
cloudflare.com mail exchanger = 5 mxa-canary.global.inbound.cf-emailsecurity.net.
cloudflare.com mail exchanger = 5 mxb-canary.global.inbound.cf-emailsecurity.net.
cloudflare.com mail exchanger = 10 mxa.global.inbound.cf-emailsecurity.net.
cloudflare.com mail exchanger = 10 mxb.global.inbound.cf-emailsecurity.net.
Authoritative answers can be found from:nslookup -type=AAAA isitdns.net 1.1.1.1Server: 1.1.1.1
Address: 1.1.1.1#53
Non-authoritative answer:
Name: isitdns.net
Address: 2606:4700:3032::6815:38d3
Name: isitdns.net
Address: 2606:4700:3036::ac43:9bf2nslookup -type=TXT cloudflare.com 1.1.1.1Server: 1.1.1.1
Address: 1.1.1.1#53
Non-authoritative answer:
cloudflare.com text = "v=spf1 ip4:199.15.212.0/22 ip4:173.245.48.0/20 include:_spf.google.com include:spf1.mcsv.net include:spf.mandrillapp.com include:mail.zendesk.com include:stspg-customer.com include:_spf.salesforce.com -all"
cloudflare.com text = "apple-domain-verification=DNnWJoArJobFJKhJ"
Authoritative answers can be found from:The SPF record above is one long TXT string and is shown verbatim; your terminal will soft-wrap it. That is normal for SPF. The real answer also carries two dozen more site-verification TXT records (Google, Facebook, Atlassian, Stripe, and so on), trimmed here for space; big domains accumulate these.
Reverse lookup (the ptr record). Not every IP has a PTR; Cloudflare's shared anycast website IPs do not, so use a resolver IP that does:
nslookup 1.1.1.22.1.1.1.in-addr.arpa name = security.cloudflare-dns.com.
Authoritative answers can be found from:Force FQDN treatment, no search-suffix appended:
nslookup webmail.On Windows: Resolve-DnsName is the modern PowerShell alternative#
Windows admins have both nslookup and PowerShell's Resolve-DnsName. The latter is richer and scriptable:
Resolve-DnsName isitdns.net -Type MX -Server 1.1.1.1
Resolve-DnsName isitdns.net -DnssecOkReference: Microsoft Learn: Resolve-DnsName.
dig: the troubleshooter's tool#
One-liner shape#
dig [@server] [name] [type] [+flags]Defaults: type = A, server = first entry in /etc/resolv.conf, no search-suffix append.
Plain A lookup:
dig @1.1.1.1 isitdns.net;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63561
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; QUESTION SECTION:
;isitdns.net. IN A
;; ANSWER SECTION:
isitdns.net. 20 IN A 104.21.56.211
isitdns.net. 20 IN A 172.67.155.242
;; Query time: 1 msec
;; SERVER: 1.1.1.1#53(1.1.1.1)
;; MSG SIZE rcvd: 72The ad in the flags line means 1.1.1.1 validated the dnssec chain for this answer. dig sets the AD bit in its queries by default (+adflag), so a validating resolver reports validation status even on a plain lookup; you only see ad when the zone is signed and the resolver validates.
nslookup equivalent:
nslookup isitdns.net 1.1.1.1Type + server:
dig @1.1.1.1 isitdns.net MXnslookup equivalent:
nslookup -type=MX isitdns.net 1.1.1.1Just the answer record(s):
dig +short isitdns.net104.21.56.211
172.67.155.242dig +noall +answer isitdns.netisitdns.net. 20 IN A 104.21.56.211
isitdns.net. 20 IN A 172.67.155.242nslookup cannot suppress the header and server lines. Use
dig +shortordig +noall +answerin scripts.
dnssec chain: request signatures alongside the answer:
dig @1.1.1.1 isitdns.net +dnssec;; flags: qr rd ra ad; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
;; ANSWER SECTION:
isitdns.net. 300 IN A 104.21.56.211
isitdns.net. 300 IN A 172.67.155.242
isitdns.net. 300 IN RRSIG A 13 2 300 20260718170208 20260716150208 34505
isitdns.net. zH57FliYkBTYS23EkQmkyyPSVthWuEgKmsqJZng1KRlg4
Xg1038S12daZXJsqdcnVxEc4Bl0b6YR2rqW/+H70A==The RRSIG timestamps, signature bytes, and TTLs above are a snapshot. Cloudflare re-signs continuously, so the inception/expiration window and signature will differ every time you run this. The key tag (34505) and algorithm (13) stay put until the key rolls.
isitdns.net is fully signed and anchored. The DS record at .net (keytag 2371, ECDSAP256SHA256) chains up to the root, so a validating resolver sets the AD flag on every response.
nslookup cannot show RRSIG records or the DO/AD bits. Use
dig +dnssecorcurlDoH for DNSSEC inspection.
Walk the hierarchy from root:
dig +trace isitdns.netnslookup cannot do
+trace. Use dig.
Ask an authoritative server directly, no recursion:
๐ง Demo server note. The
probe.isitdns.netdemo server is being rebuilt, so the specificpns1.isitdns.netlookups below may not answer right now. The mechanics they teach (theaabit,+norec, reading the flags line) are unchanged and work against any authoritative server.
The query below targets pns1.isitdns.net, a conventional BIND authoritative server for the
probe.isitdns.net zone. Because it is authoritative, it sets the aa (Authoritative Answer) bit
and answers with NOERROR. Cloudflare's anycast NS (coleman, hera) behave exactly the same
way: they answer RD=0 (+norec) queries, as every authoritative server must
(RFC 1034 section 4.3.2), and their
responses show the same textbook flag pattern, aa set and no ra. So while pns1 is offline you
can run this exact demo against coleman.ns.cloudflare.com with isitdns.net; a live example
follows below.
On a network that intercepts port 53 (captive portals and some home routers do this), a
@serverquery is answered by the interceptor, not the server you named. You may see onlyrd rawithoutaa. That is your network, not the server. See dig-flags for the full flag breakdown.
dig @pns1.isitdns.net probe.isitdns.net SOA +norec;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12345
;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; QUESTION SECTION:
;probe.isitdns.net. IN SOA
;; ANSWER SECTION:
probe.isitdns.net. 300 IN SOA pns1.isitdns.net. hostmaster.isitdns.net. \
2026061511 7200 3600 1209600 300The serial number (
2026061511) is a snapshot from the time this example was written. The live value will differ; that is expected.
The aa flag confirms pns1 is the authoritative source, not a cache. The absence of ra
(Recursion Available) confirms it did not forward the query.
The same pattern, live right now, against Cloudflare's authoritative NS for isitdns.net:
dig @coleman.ns.cloudflare.com isitdns.net SOA +norec;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 57923
;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; QUESTION SECTION:
;isitdns.net. IN SOA
;; ANSWER SECTION:
isitdns.net. 1800 IN SOA coleman.ns.cloudflare.com. dns.cloudflare.com. \
2409741473 10000 2400 604800 1800Same caveat as above: the SOA serial is a snapshot and the live value will differ. The flags are the point:
aawith nora.
nslookup equivalent (the -norecurse flag sets RD=0, matching +norec):
nslookup -norecurse -type=SOA probe.isitdns.net pns1.isitdns.netnslookup does not surface the aa bit in its default output (Windows nslookup buries header
flags in set debug mode), so you cannot confirm authoritative status from a plain nslookup run.
If you need to confirm a server is truly authoritative and not forwarding, use dig and look for
aa in the flags line.
Skip dnssec validation (Checking Disabled):
dig +cd isitdns.netnslookup cannot set the CD bit. Use dig.
+norec tells the server not to recurse: useful when you are querying an authoritative server directly and do not want it to forward the query. +cd sets the Checking Disabled bit, telling the resolver to skip dnssec validation and return whatever it has; useful for debugging a broken DNSSEC chain. A full flag tour is in dig-flags. A real-records hands-on tour is in dig-along.
Why dig is the troubleshooter's tool#
Three reasons:
- It tells you everything the wire said. Header flags (
aa,ad,ra,rd,tc,cd), rcode, EDNS options, RRSIGs: all visible. - It does not "help." No search-suffix append. No silent retries through alternate transports. No reordering. What you ask is what you get.
- It's scriptable.
+short,+noall +answer, machine-readable output, exit codes. Bash, Python wrappers, monitoring scripts all usedig.
Does dig ever append search suffixes?#
By default: no. But +search will turn it on:
dig webmail +search+nosearch is the default: most people don't realize the toggle exists. If you are troubleshooting and a colleague says "but nslookup webmail worked!", dig +search webmail is the equivalent comparison. nslookup's behavior matches dig +search by default.
Side-by-side: same question, both tools#
Asking a public resolver for the A record of isitdns.net:
nslookup isitdns.net 1.1.1.1Server: 1.1.1.1
Address: 1.1.1.1#53
Non-authoritative answer:
Name: isitdns.net
Address: 104.21.56.211
Name: isitdns.net
Address: 172.67.155.242
Name: isitdns.net
Address: 2606:4700:3032::6815:38d3
Name: isitdns.net
Address: 2606:4700:3036::ac43:9bf2dig @1.1.1.1 isitdns.net;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 27584
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; QUESTION SECTION:
;isitdns.net. IN A
;; ANSWER SECTION:
isitdns.net. 20 IN A 104.21.56.211
isitdns.net. 20 IN A 172.67.155.242
;; Query time: 1 msec
;; SERVER: 1.1.1.1#53(1.1.1.1)
;; MSG SIZE rcvd: 72Same A records, but notice the difference in scope. nslookup quietly ran a second AAAA lookup and blended the two answers into one list; dig asked exactly the one question you gave it. And dig says "here are the flags, the rcode, the TTLs, every record in the answer set, the server that answered, how long it took, and what bytes were on the wire."
Use the one that fits the question.
When to reach for which#
| Scenario | Better tool | Why |
|---|---|---|
| "What is the IP of webmail?" on a Windows host | nslookup | Right there in cmd, interactive mode is comfortable |
"Why is this query returning SERVFAIL?" | dig | Need to see flags, EDE codes, rcode reason |
| Scripted health check in a cron job | dig | +short and exit codes make it pipe-friendly |
| Demo to someone who has never run a DNS command | nslookup | Output reads like prose |
| Validating a dnssec chain | dig +dnssec (and delv) | Surface RRSIGs and EDE codes; use delv for definitive chain validation |
| Capturing every byte to compare against expected | dig +qr | Shows both query and response with full detail |
| Quick check on a Windows host with no extra tools installed | nslookup | Default-installed, no IT ticket needed |
| Walking through what each section of DNS output means | dig | Sections are named and stable: see dig-along for a real-records walkthrough |
A reasonable rule: nslookup for answers, dig for understanding.
Other tools worth knowing about (footnote)#
| Tool | Where | Why mention it |
|---|---|---|
host | Linux / BIND | Tiny wrapper over the same library. host -t MX isitdns.net is faster to type than nslookup if you know it exists. |
delv | BIND 9.10+ | The dnssec-validating sibling of dig. Use when you need a definitive "this chain validates / does not validate" answer. Cited heavily in dnssec-troubleshooting. |
kdig | Knot DNS package | Like dig but with first-class dot-doh (DoT/DoH/DoQ) flags. Useful when probing encrypted transports. |
drill | NLnet Labs | Another dig-alike, popular in research contexts. |
Resolve-DnsName | Windows PowerShell | Scriptable Microsoft-side dig equivalent. Linked above. |
mDNS clients (dns-sd, avahi-browse) | macOS / Linux | For .local resolution; not part of unicast DNS. |
Cheat-sheet card#
nslookup dig
-------- ---
Quick A lookup: nslookup isitdns.net dig @1.1.1.1 isitdns.net
Pick resolver: nslookup isitdns.net 1.1.1.1 dig @1.1.1.1 isitdns.net
Record type: nslookup -type=MX isitdns.net 1.1.1.1 dig @1.1.1.1 isitdns.net MX
Reverse (PTR) lookup: nslookup 1.1.1.2 dig -x 1.1.1.2
Suppress chatter: (not available) dig +short isitdns.net
Force FQDN, no suffix: nslookup isitdns.net. (default behavior)
Apply search suffix: (default behavior) dig +search webmail
Interactive session: nslookup / server / set / exit n/a
DNSSEC validation: (cannot show RRSIG/AD) dig +dnssec / delv
Show DNS header flags: set debug (Windows, partial) (always in default output)
No recursion (RD=0): nslookup -norecurse dig +norec
+trace / +cd: (not available) dig +trace / +cdSee also#
- dig-along: every common record type, live, hands-on
- dig-flags: every dig flag explained
- anatomy-of-a-query: what happens between the time you hit Enter and the answer arrives
- query-types: record types and rcodes explained
- dnssec: how DNSSEC signing works
- dnssec-troubleshooting: where
delvcomes in - dot-doh: DoT, DoH, and DoQ for encrypted DNS queries
- ptr: reverse DNS and the in-addr.arpa zone
- wireshark-dns-filters: when even
dig +qris not enough - [Microsoft Learn:
nslookupreference][ms-nslookup] - Microsoft Learn:
Resolve-DnsNamePowerShell module - [ISC BIND 9:
digmanpage][isc-dig] - ISC Knowledgebase: broader DNS / BIND reference