> ## 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.

# nslookup: Quick DNS Queries That Still Matter
- URL: https://www.pinglabz.com/nslookup-linux/
- Published: 2026-08-19T14:25:12.000Z
- Updated: 2026-08-19T14:25:12.000Z
- Description: Declared deprecated for twenty years and still on every machine. What it does well, where it will mislead you, and the debug flag nobody uses.
- Author: Jaime
- Tags: Linux, DNS, Troubleshooting

`nslookup` has been called deprecated for roughly twenty years and it is still on every machine you will ever log into. It ships in the same package as `dig` on Linux, it is built into Windows, and it is the one DNS client a Windows admin, a Linux admin and a network engineer can all use without looking anything up. That is worth something, and it is why the tool refuses to die.

This guide covers what `nslookup` does well, where its output will actively mislead you, and the handful of flags that make it genuinely useful. Every capture is real output from a Debian 13 host querying an authoritative server for `pinglabz.lab` across a Cisco Modeling Labs topology, with live public-resolver queries where they make the point better. It is part of the [Linux networking commands](https://www.pinglabz.com/linux-networking-commands/) cluster.

## The shape of the command

The syntax is `nslookup [options] name [server]`. The server goes last, with no `@` and no flag, which is the first thing that catches people coming from `dig`:

```
j@llmbits:~$ nslookup www.pinglabz.lab 10.77.3.10
Server:		10.77.3.10
Address:	10.77.3.10#53

Name:	www.pinglabz.lab
Address: 10.77.2.10
Name:	www.pinglabz.lab
Address: 2001:db8:77:2::10
```

Two things are already happening that `dig` would not do. First, one command produced two queries: A and AAAA. `nslookup` asks for both by default, so a dual-stack name gives you both families in one shot. Second, the `Server:` block at the top tells you exactly which resolver answered, which is genuinely useful and is the reason a lot of people keep reaching for it.

Leave the server off and it uses whatever `/etc/resolv.conf` says. Note the extra line that appears:

```
j@llmbits:~$ nslookup pinglabz.com
Server:		45.90.28.181
Address:	45.90.28.181#53

Non-authoritative answer:
Name:	pinglabz.com
Address: 178.128.137.126
```

"Non-authoritative answer" is `nslookup`'s way of saying the `aa` flag was not set, so this came from a cache rather than from a server that holds the zone. It is the same information `dig` puts in the flags line, just spelled out. Against the lab's authoritative server that line is absent, which is how you tell the two situations apart.

## Record types with -query= or -type=

Both spellings work and mean the same thing. `-query=` is the documented one, `-type=` is what most people type:

```
j@llmbits:~$ nslookup -query=MX pinglabz.lab 10.77.3.10
Server:		10.77.3.10
Address:	10.77.3.10#53

pinglabz.lab	mail exchanger = 10 mail.pinglabz.lab.
pinglabz.lab	mail exchanger = 20 mail2.pinglabz.lab.

j@llmbits:~$ nslookup -query=NS pinglabz.lab 10.77.3.10
pinglabz.lab	nameserver = ns1.pinglabz.lab.
pinglabz.lab	nameserver = ns2.pinglabz.lab.

j@llmbits:~$ nslookup -query=TXT pinglabz.lab 10.77.3.10
pinglabz.lab	text = "v=spf1 ip4:10.77.3.10 ip4:10.77.2.10 -all"
pinglabz.lab	text = "pinglabz-lab-verification=phase3"

j@llmbits:~$ nslookup -query=SRV _sip._udp.pinglabz.lab 10.77.3.10
_sip._udp.pinglabz.lab	service = 10 60 5060 srv1.pinglabz.lab.
```

`nslookup` spells out what `dig` abbreviates. "mail exchanger", "nameserver", "text", "service" instead of MX, NS, TXT, SRV. That verbosity is why it reads well to someone who does not live in DNS, and why it is annoying to parse in a script.

SOA gets broken out field by field automatically, no `+multiline` needed:

```
j@llmbits:~$ nslookup -query=SOA pinglabz.lab 10.77.3.10
Server:		10.77.3.10
Address:	10.77.3.10#53

pinglabz.lab
	origin = ns1.pinglabz.lab
	mail addr = hostmaster.pinglabz.lab
	serial = 2026081901
	refresh = 7200
	retry = 3600
	expire = 1209600
	minimum = 3600
```

That is arguably nicer than `dig +multiline`. If you are comparing serials between a primary and a secondary at 2am, this is a perfectly good tool for the job.

## Reverse lookups need no flag

Give `nslookup` an address instead of a name and it works it out. No `-x`, no `-t PTR`:

```
j@llmbits:~$ nslookup 10.77.3.10 10.77.3.10
10.3.77.10.in-addr.arpa	name = srv1.pinglabz.lab.

j@llmbits:~$ nslookup 10.77.2.10 10.77.3.10
10.2.77.10.in-addr.arpa	name = www.pinglabz.lab.
```

Notice the `Server:` header is gone on a reverse lookup. That inconsistency is characteristic of the tool: the output format shifts depending on what you asked, which is fine for a human and awful for a parser.

## What a CNAME looks like

Aliases are shown with the chain resolved, and again both address families come back:

```
j@llmbits:~$ nslookup portal.pinglabz.lab 10.77.3.10
Server:		10.77.3.10
Address:	10.77.3.10#53

portal.pinglabz.lab	canonical name = www.pinglabz.lab.
Name:	www.pinglabz.lab
Address: 10.77.2.10
Name:	www.pinglabz.lab
Address: 2001:db8:77:2::10
```

"Canonical name" is CNAME spelled out. On a real CDN-fronted domain the chain gets long, and `nslookup` follows all of it:

```
j@llmbits:~$ nslookup www.pinglabz.com 9.9.9.9
Server:		9.9.9.9
Address:	9.9.9.9#53

Non-authoritative answer:
www.pinglabz.com	canonical name = ping-labz.ghost.io.
ping-labz.ghost.io	canonical name = ghost.map.fastly.net.
Name:	ghost.map.fastly.net
Address: 151.101.131.7
Name:	ghost.map.fastly.net
Address: 151.101.195.7
Name:	ghost.map.fastly.net
Address: 2a04:4e42:600::775
Name:	ghost.map.fastly.net
Address: 2a04:4e42::775
```

Eight addresses across two CNAMEs, all readable without knowing any DNS notation. This is the case where `nslookup` is arguably the better tool: hand this output to someone who does not do DNS for a living and they can follow it.

## Failures and exit status

NXDOMAIN comes back as a plain English complaint:

```
j@llmbits:~$ nslookup nothere.pinglabz.lab 10.77.3.10
Server:		10.77.3.10
Address:	10.77.3.10#53

** server can't find nothere.pinglabz.lab: NXDOMAIN
```

The RCODE is right there at the end of the line, so you still get the real status word. And unlike `dig`, the exit status is useful:

```
j@llmbits:~$ nslookup gw.pinglabz.lab 10.77.3.10; echo "exit status: $?"
Server:		10.77.3.10
Address:	10.77.3.10#53

Name:	gw.pinglabz.lab
Address: 10.77.0.1

exit status: 0

j@llmbits:~$ nslookup nothere.pinglabz.lab 10.77.3.10 > /dev/null 2>&1; echo "exit status: $?"
exit status: 1
```

That is a real advantage over `dig`, which returns 0 on NXDOMAIN because the query itself succeeded. If you want a name lookup that fails a shell test when the name does not exist, `nslookup` and `host` both give it to you and `dig` does not.

An unreachable server produces a different failure, with no RCODE at all because nothing answered:

```
j@llmbits:~$ nslookup -timeout=2 -retry=1 pinglabz.lab 10.77.9.9
;; communications error to 10.77.9.9#53: host unreachable
;; no servers could be reached
```

"Host unreachable" against "server can't find" is the distinction that matters. The first is a routing or firewall problem, the second is a DNS data problem. Different team, usually.

## Debug mode, the part people forget exists

This is the flag that makes `nslookup` competitive with `dig`, and almost nobody uses it. `-debug` prints the actual query and response structure:

```
j@llmbits:~$ nslookup -debug www.pinglabz.lab 10.77.3.10
Server:		10.77.3.10
Address:	10.77.3.10#53

------------
    QUESTIONS:
	www.pinglabz.lab, type = A, class = IN
    ANSWERS:
    ->  www.pinglabz.lab
	internet address = 10.77.2.10
	ttl = 3600
    AUTHORITY RECORDS:
    ADDITIONAL RECORDS:
------------
Name:	www.pinglabz.lab
Address: 10.77.2.10
------------
    QUESTIONS:
	www.pinglabz.lab, type = AAAA, class = IN
    ANSWERS:
    ->  www.pinglabz.lab
	has AAAA address 2001:db8:77:2::10
	ttl = 3600
    AUTHORITY RECORDS:
    ADDITIONAL RECORDS:
------------
Name:	www.pinglabz.lab
Address: 2001:db8:77:2::10
```

Two separate transactions, each with its own question, answer, authority and additional section, and the TTL exposed. That is most of what you wanted `dig` for. It also makes the dual-query behavior visible: `nslookup` really is sending two packets for one command.

## The flags worth remembering

**`-query=TYPE`**Record type. `-type=` is a synonym. Without it you get A and AAAA. 

**`-debug`**Full query and response structure with TTLs. The single most underused flag on this tool. 

**`-timeout=N`**Seconds to wait. Default is 5, which is far too long when probing a dead server. 

**`-retry=N`**Attempts before giving up. Pair with `-timeout` to fail fast. 

**`-vc`**Virtual circuit, meaning use TCP. The equivalent of `dig +tcp`, and the way to test whether TCP 53 is permitted. 

**`-port=N`**Query a nameserver on a non-standard port. Useful against a stub or a test instance. 

**`-norecurse`**Clear the RD bit. Against a cache this asks "do you already know this?" without triggering a lookup. 

All of these combine, and combining `-timeout` with `-retry` is how you stop a probe from hanging for fifteen seconds:

```
j@llmbits:~$ nslookup -port=53 -timeout=2 -retry=1 srv1.pinglabz.lab 10.77.3.10
Server:		10.77.3.10
Address:	10.77.3.10#53

Name:	srv1.pinglabz.lab
Address: 10.77.3.10
Name:	srv1.pinglabz.lab
Address: 2001:db8:77:3::10
```

## Truncation is handled, and announced

When a UDP response does not fit, `nslookup` retries over TCP and tells you it did. Google's TXT records are a reliable way to trigger it:

```
j@llmbits:~$ nslookup -query=TXT google.com 1.1.1.1
;; Truncated, retrying in TCP mode.
Server:		1.1.1.1
Address:	1.1.1.1#53

Non-authoritative answer:
google.com	text = "cisco-ci-domain-verification=47c38bc8c4b74b7233e9053220c1bbe76bcc1cd33c7acf7acd36cd6a5332004b"
google.com	text = "onetrust-domain-verification=6d685f1d41a94696ad7ef771f68993e0"
google.com	text = "apple-domain-verification=30afIBcvSuDV2PLX"
google.com	text = "v=spf1 include:_spf.google.com ~all"
google.com	text = "facebook-domain-verification=22rm551cu4k0ab0bxsw536tlds4h95"
[... ten more ...]
```

That first line is a free diagnostic. If you see "Truncated, retrying in TCP mode" and then nothing, TCP 53 is being blocked somewhere in the path, and you have found your intermittent DNS failure.

## Interactive mode

Run `nslookup` with no arguments and it drops into a prompt where you set state once and then fire off queries. This is where it beats `dig` for exploratory work, because you are not retyping the server on every line. Driven from a here-doc so the whole session is reproducible:

```
j@llmbits:~$ nslookup
Default server: 10.77.3.10
Address: 10.77.3.10#53
> server 10.77.3.10
> set type=MX
> pinglabz.lab
Server:		10.77.3.10
Address:	10.77.3.10#53

pinglabz.lab	mail exchanger = 10 mail.pinglabz.lab.
pinglabz.lab	mail exchanger = 20 mail2.pinglabz.lab.
> set type=A
> www.pinglabz.lab
Server:		10.77.3.10
Address:	10.77.3.10#53

Name:	www.pinglabz.lab
Address: 10.77.2.10
> exit
```

The commands worth knowing inside the prompt: `server <addr>` to switch resolver, `set type=X` to change record type, `set debug` or `set d2` for increasing verbosity, `set all` to print current state, and `exit` to leave. Everything else is a name to look up.

## Where nslookup will mislead you

Three real traps, in order of how often they cost people time:

**It hides the flags** "Non-authoritative answer" is the only flag information you get. You cannot see `ad` for DNSSEC validation, and you cannot see `ra` to tell whether the server offers recursion at all. 

**It hides the TTL** Not shown at all unless you use `-debug`. Since a counting-down TTL is how you spot a cached answer, this matters more than it sounds. 

**It queries twice** A and AAAA by default. Fine for a human, misleading when you are counting packets or timing a resolver. 

**Its output format shifts** Forward, reverse, MX and SOA lookups all print differently. Parsing it in a script is a losing game. Use `dig +short` instead. 

There is also the "deprecated" question, which comes up every time somebody uses it. The short version: ISC did announce deprecation years ago, then kept shipping and maintaining it, and current BIND still builds it. The version on this Debian 13 host is `nslookup 9.20.26`, from BIND 9.20, released in 2026\. It is not going anywhere. Use it when it is the right shape for the job, and use `dig` when you need to see the protocol.

## When to reach for which tool

**nslookup**Cross-platform muscle memory, interactive exploration, dual-stack in one command, and output you can paste into a ticket for a non-specialist. 

**dig**Anything where the protocol matters: flags, TTLs, authority sections, DNSSEC, delegation traces, transport testing. 

**host**One name, one line, right now. And the cleanest exit status of the three for scripting. 

## FAQ

### Is nslookup really deprecated?

It was announced as deprecated by ISC a long time ago, but it is still built, shipped and maintained as part of BIND, and it is a first-class citizen on Windows. Treat "deprecated" as "not the tool to reach for when you need protocol detail", not as "about to be removed".

### Why does nslookup show a different answer from dig?

Usually because they queried different servers. `nslookup` with no server argument uses `/etc/resolv.conf`; `dig @something` does not. Check the `Server:` line in the `nslookup` output against the `SERVER:` line in `dig +stats`. If they match and the answers still differ, you are looking at a caching difference, and the TTL from `nslookup -debug` will tell you.

### How do I see the TTL in nslookup?

`nslookup -debug`. There is no other way. It appears in the answers block as `ttl = 3600`.

### Can nslookup do a zone transfer?

In interactive mode, `ls -d domain` attempts one. On any correctly configured authoritative server it will be refused, which is the outcome you want. If it succeeds against your own infrastructure from an unauthorized host, fix that today. The offensive use of open transfers is covered in the [DNS enumeration cluster](https://www.pinglabz.com/dns-enumeration/).

### Does nslookup use /etc/hosts?

No. Like `dig`, it speaks DNS directly to a nameserver and skips the C library resolver entirely, so `/etc/hosts`, mDNS and NSS modules are all invisible to it. That is exactly why a name can work in `ping` and fail in `nslookup`, or the reverse. [How Linux resolves names](https://www.pinglabz.com/linux-dns-resolution/) covers the full path.

### What is the difference between set debug and set d2?

`set debug` shows the parsed question and answer sections, as in the `-debug` capture above. `set d2` adds the raw query packet on top of that. Use `d2` when you suspect the query itself is malformed or the name is not what you think it is.

## Key takeaways

- The server goes last with no flag: `nslookup name server`. That single syntax difference is the most common stumble coming from `dig`.
- It queries A and AAAA by default, so one command covers dual stack. That is a feature for humans and a nuisance for packet counting.
- "Non-authoritative answer" means the `aa` flag was not set. Its absence means you reached an authority.
- `-debug` gets you questions, answers, authority sections and TTLs, and closes most of the gap with `dig`.
- Exit status is 0 on success and 1 on NXDOMAIN, which makes it scriptable in a way `dig` is not.
- "Truncated, retrying in TCP mode" is a free diagnostic. If the retry then fails, TCP 53 is blocked.
- Do not parse its output. The format changes with the query type. Use `dig +short` or `host` for machine-readable answers.
- Reported deprecated, still shipping in BIND 9.20 in 2026, still the only DNS client every operating system agrees on.

For the protocol-level view of the same queries, read [the complete dig guide](https://www.pinglabz.com/dig-command/). For the fastest one-line form, see [host](https://www.pinglabz.com/host-command-linux/). For why a name resolves in one tool and not another, read [how Linux resolves names](https://www.pinglabz.com/linux-dns-resolution/). All of them are indexed on the [Linux networking commands](https://www.pinglabz.com/linux-networking-commands/) pillar.