Troubleshooting DNS with NSLookup and dig

Posted On 2009-05-27 by dwirch
Tags: Networking Tutorial Windows Commandline 
Views: 23405

To be proficient at troubleshooting name server problems, you'll need a special tool to make DNS queries, one that gives you complete control. We'll cover nslookup in this tutorial because it's distributed with Windows Server 2003 and with many other operating systems. We'll also cover another query tool, dig, that isn't part of Windows. It provides similar functionality and doesn't suffer from nslookup's deficiencies.

Much of the time you'll use nslookup to make queries in the same way the resolver makes them. Sometimes, though, you'll use nslookup to query other name servers as a name server would. Which one you emulate will depend on the problem you're trying to debug. You might wonder, "How accurately does nslookup emulate a resolver or a name server? Does nslookup actually use the Windows resolver library routines?" No, nslookup uses its own routines for querying name servers, but those routines are based on the resolver routines. Consequently, nslookup's behavior is very similar to the resolver's behavior, but it does differ slightly. We'll point out some of those differences. As for emulating name server behavior, nslookup allows you to query another server with the same query message that a name server would use, but the retransmission scheme is quite different. Like a name server, though, nslookup can perform a zone transfer to pull a copy of a zone's data. So nslookup does not exactly emulate either the resolver or the name server, but it does emulate them well enough to make a good troubleshooting tool. Let's delve into those differences we've alluded to.

Multiple Servers

nslookup talks to only one name server at a time. This is the major difference between nslookup's behavior and the resolver's behavior. The resolver makes use of all the name servers listed in the Windows resolver configuration window. If two name servers are listed, the resolver tries the first name server, then the second, then the first, then the second, until it receives a response or gives up. The resolver does this for every query. On the other hand, nslookup tries only the first name server listed. But you want your troubleshooting tool to talk with only one name server so you can reduce the number of variables when analyzing a problem. If nslookup used more than one name server, you wouldn't have as much control over your troubleshooting session.


The nslookup timeouts are similar to the resolver timeouts when the resolver is querying only one name server. A name server's timeouts, however, are based on how quickly the remote server answered the last query, a dynamic measure. nslookup will never match name server timeouts, but that's not a problem either. When you're querying remote name servers with nslookup, you probably care only what the response was, not how long it took.

The Search List

nslookup implements the search list just as the resolver code does. Name servers don't implement search lists, so, to act like a name server, the nslookup search function must be turned off?more on that later.

Zone Transfers

nslookup will do zone transfers just like a name server. Unlike the name server, though, nslookup does not check SOA serial numbers before pulling the zone data; you'll have to do that manually, if you want to.

Using NetBIOS Names

This last point doesn't compare nslookup to the resolver or name server but rather to ways of looking up names in general. nslookup, as distributed by Microsoft, uses only DNS; you can't use it to look up NetBIOS names via broadcast, LMHOSTS, or WINS. Before using nslookup to diagnose your problem, you need to determine if your problem is really with DNS. For example, if an application is using a different IP address than you expect, perhaps it's treating a value as a NetBIOS name and not a DNS name. To diagnose this kind of problem, you need to understand how the Windows resolver works. Just remember that nslookup talks only to name servers.

Interactive Versus Noninteractive

Let's start our tutorial on nslookup by looking at how to start and stop it. You can run nslookup either interactively or noninteractively. If you want to look up only one piece of data, you should use the noninteractive form. If you plan on doing something more extensive, such as changing servers or options, use an interactive session.

To start an interactive session, just type nslookup:

C:\> nslookup
Default Server:

> ^Z

If you need help, type ? or help.

When you want to exit, type ^Z (Ctrl-Z) and press Enter. You can also exit from nslookup with ^C or ^Break (Ctrl-Break). This behavior is different from nslookup's operation on a Unix host, where if you send nslookup an interrupt, it catches it, stops whatever it is doing (like a zone transfer), and gives you the > prompt. There's no way to just interrupt Microsoft's nslookup: you just have to stop nslookup completely and restart it.

For a noninteractive lookup, include the name you are looking up on the command line:

C:\> nslookup carrie


nslookup has its own set of dials and knobs called option settings. All the option settings can be changed. We'll discuss here what each of the options means. We'll use the rest of the tutorial to show you how to use them.

C:\> nslookup
Default Server:

> set all
Default Server:

Set options:

> ^Z

Before we get into the options, we need to cover the introductory lines. The default name server is This means that every query sent by nslookup will be sent to terminator.

The options come in two flavors: Boolean and value. The options that do not have an equals sign after them are Boolean options and they are either "on" or "off." The value options can take on different, well, values. How can we tell which Boolean options are on and which are off? The option is off when a "no" precedes the option's name. nodebug means that debugging is off. As you might guess, the option search is on.

How you change Boolean or value options depends on whether or not you are using nslookup interactively. In an interactive session, you change an option with the set command, as in set debug or set From the command line, you omit the word set and precede the option with a hyphen, as in nslookup -debug or nslookup The options can be abbreviated to their shortest unique string?for example, nodeb for nodebug. In addition to its abbreviation, the querytype option can also be entered simply as type.

Let's go through each of the options:

[no]debugDebugging is turned off by default. If it is turned on, nslookup displays the complete contents of the response messages from the name server. See [no]d2 for a discussion of debug level 2.
[no]defname This option reflects nslookup's BIND heritage. By default, nslookup adds the default domain name to names without a dot in them. Before search lists existed, the BIND resolver code would add the default domain only to names without any dots in them; this option reflects that behavior. nslookup can implement the pre-search list behavior (with search off and defname on), or it can implement the search list behavior (with search on).
[no]search The search option "overshadows" the default domain name (defname) option. That is, defname applies only if search is turned off. By default, nslookup appends the domain names in the search list (srchlist) to names that don't end in a dot. nslookup's search list is constructed from the Append these DNS suffixes field on the DNS tab of the Advanced TCP/IP Settings window.
[no]recurse nslookup requests recursive service by default. This turns on the recursion-desired bit in query messages. The Windows resolver sends recursive queries in the same way. Name servers, however, send nonrecursive queries to other name servers.
[no]d2 Debugging at level 2 is turned off by default. If it is turned on, you see the query messages sent to the name server in addition to the regular debugging output. Turning on d2 also turns on debug. Turning off d2 turns off d2 only; debug is left on. Turning off debug turns off both debug and d2.
[no]vc By default, nslookup makes queries using UDP instead of over a TCP connection (virtual circuit). Most Windows resolver queries are made with UDP, so the default nslookup behavior matches the resolver.
[no]ignoretc By default, nslookup doesn't ignore truncated messages. If a message is received that has the "truncated" bit set?indicating that the name server couldn't fit all the important information in the UDP response message?nslookup doesn't ignore it; it retries the query using a TCP connection instead of UDP.
port=53 The DNS service is on port 53. You can start a name server on another port?for debugging purposes, for example?and nslookup can be directed to use that port.
type=A By default, nslookup looks up A (address) resource record types. In addition, if you type in an IP address (and the nslookup query type is address or pointer), nslookup inverts the address, appends, and looks up PTR (pointer) data instead.
class=IN The only class that matters is Internet. Well, there's the Hesiod (HS) class, too, if you are an MITer or run Ultrix.
timeout=2 If the name server doesn't respond within two seconds, nslookup resends the query and waits another two seconds before giving up and printing a timeout message. The Windows resolver uses different timeouts when querying a single name server (see Chapter 6).
retry=1 The query is sent just once before giving up. Again, the Windows resolver behaves slightly differently as discussed in Chapter 6.
root=A.ROOT-SERVERS.NET A convenience command called root switches your default server to the server named here. Executing the root command from nslookup's prompt is equivalent to executing server A.ROOT-SERVERS.NET. You can change the default "root" server with set root=server. This is the default domain name appended if the defname option is on. If the defname option is not on, no default domain name is appended.
[no]MSxfr The Microsoft DNS Server implements a feature that Microsoft calls "fast" zone transfers. Those of you familiar with the BIND name server know this as the "many answers" zone-transfer format, in which multiple records are packed into the answer section of a single DNS message during a zone transfer. (The method implemented by older BIND name servers uses one DNS message per record, which is somewhat wasteful of bandwidth.) This option indicates whether or not to request one of these "fast" zone transfers.
IXFRversion=1 The Microsoft DNS Server also supports a protocol called incremental zone transfer (IXFR). IXFR requests include a version number. The default value of 1 corresponds to the IXFR version supported by the Microsoft DNS Server. At this point, there's no reason to change this value. If search is on, t hese domain names are appended to names that do not end in a dot. The domain names are listed in the order in which they will be tried and are separated by slashes.

Avoiding the Search List

nslookup implements the search list, as the resolver does. When you are debugging, the search list can get in your way. You need to either turn the search list off completely (set nosearch) or add a trailing dot to the fully qualified domain name you are looking up. We prefer the latter, as you'll see in our examples.

Common Tasks

You'll come to use nslookup for little chores almost every day: for example, finding out the IP address or MX records for a given domain name or querying a particular name server for data. We'll cover these common tasks before moving on to the more occasional stuff.

Looking Up Different Data Types

By default, nslookup looks up the address for a name or the name for an address. You can look up any data type by changing the querytype, as we show in this example:

C:\> nslookup Default Server:
> misery Look up address.
> Look up name.
> set type=mx Look up MX data.
> wormhole
Address: MX preference = 10, mail exchanger = internet address = internet address =
> set q=any Look up data of any type.
> diehard
Address: internet address = MX preference = 10, mail exchanger = internet address =

These are only a few of the valid DNS data types, of course.

Authoritative Versus Nonauthoritative Answers

If you've used nslookup before, you might have noticed that it sometimes precedes its answers with the phrase "Non-authoritative answer":

Default Server:
Non-authoritative answer:

This phrase indicates that the name server is not authoritative for the data in the answer. (Recall that a name server is authoritative for data when it's a primary or secondary for the zone containing the data.) You'll see a nonauthoritative response for one of two reasons. The first is that the name server you queried didn't have the data you were looking for and had to query a remote name server to get it. The remote name server is authoritative for the data (that's the reason it was queried!) and returns it with the "authoritative answer" bit set in the DNS message header. The Microsoft DNS Server you queried puts this data in its cache and returns it to you marked nonauthoritative. If you ask for the same data again, this time the name server can answer from its cache and will mark the data nonauthoritative: that's the second reason you'll see a nonauthoritative answer.

Authoritative answers are not announced by nslookup: the absence of the nonauthoritative message means the answer is authoritative.

Notice that we ended the domain name with a trailing dot. The response would have been the same had we left it off. Sometimes it is critical that you use the trailing dot while debugging, but not always. Rather than stopping to decide if this name needs a trailing dot, we always add one if we know the name is fully qualified (except, of course, for the example where we turn off the search list).

Switching Servers

Sometimes you want to query another name server directly?for example, if you think it is misbehaving. You can switch servers with nslookup by using the server or lserver commands. The difference between server and lserver is that lserver queries your "local" server?the one you started out with?to get the address of the server you want to switch to; server uses the default server instead of the local server. This difference is important because the server that you just switched to may not be responding, as we'll show in this example:

C:\> nslookup
Default Server:

When we start up, our first server,, becomes our lserver (this will matter later on in this session):

Default Server:
*** can't find No response from server

At this point we try to switch back to our original name server. But there is no name server running on galt to look up relay's address:

> server
*** Can't find address for server No response from server

Instead of being stuck, though, we use the lserver command to have our local server look up relay's address:

> lserver
Default Server:

Since the server on galt did not respond, it's not even running a name server, it wasn't possible to look up the address of relay to switch back to using relay's name server. Here's where lserver comes to the rescue: the local name server, relay, was still responding, so we used it. Instead of using lserver, we could have recovered by using relay's IP address directly?server

You can even change servers on a per-query basis. To specify that you'd like nslookup to query a particular server for information about a given domain name, you can specify the server as the second argument on the line, after the domain name to look up?like so:

C:\> nslookup
Default Server:

And, of course, you can change servers from the command line. You can specify the server to query as the argument after the domain name to look up, like this:

C:\> nslookup -type=mx

This instructs nslookup to query for MX records for

To specify an alternate default server and enter interactive mode, you can use a hyphen in place of the domain name to look up:

C:\> nslookup -

Troubleshooting nslookup Problems

The last thing you want is to have problems with your troubleshooting tool. Unfortunately, some types of failures render the troubleshooting tool mostly useless. Other types of nslookup failures are, at best, confusing because they don't give you any direct information to work with. Although there may be a few problems with nslookup itself, most of the problems you encounter will be with name server configuration and operation. We'll cover a few odd problems here.

Looking Up the Right Data

This isn't really a problem, per se, but it can be awfully confusing. If you use nslookup to look up a type of data for a domain name and the domain name exists but no data of the type you're looking for exists, you'll get an error like this:

C:\> nslookup
Default Server:

Huh? It looks like we got an empty answer. In fact, that's exactly what happened: there are no A records for, and the response from the name server has no records in the Answer section of the message. nslookup renders this empty response from the name server as an empty response to us. It's not very helpful or clear (previous versions of nslookup printed a better response).

So what types of records do exist? You can use set type=any to find out:

> set type=any
Address: nameserver = nameserver =
primary name server =
responsible mail addr =
serial = 21
refresh = 900 (15 mins)
retry = 600 (10 mins)
expire = 86400 (1 day)
default TTL = 3600 (1 hour) MX preference = 10, mail exchanger = internet address = internet address = internet address = internet address = internet address =

Why are the IP addresses for terminator and wormhole returned? If you receive the NS records for listing these two hosts as that zone's name servers, chances are the next thing you'll want are those hosts' IP addresses. The name server anticipates that and sends along address records in the Additional section. The same thing goes for the MX record pointing to wormhole: if you get that record, you'll want wormhole's IP address next. That explains why wormhole's IP addresses show up twice, but this is arguably a bug in the Microsoft DNS Server.

No PTR Data for Name Server's Address

Here's a cryptic message:

C:\> nslookup
*** Can't find server name for address Non-existent domain
Default Server: UnKnown

The "Non-existent domain" message means that there's no PTR record for In other words, nslookup couldn't find the name for, which is the first name server the resolver is configured to query. The only reason nslookup looks up this address is to print the "Default Server" startup message. Obviously, this name server's data is messed up, at least for the zone, so nslookup prints "UnKnown."


What if your resolver is pointing to a name server that isn't running or a host that can't be reached? Here's what happens:

C:\> nslookup
DNS request timed out.
timeout was 2 seconds.
*** Can't find server name for address Timed out
Default Server: UnKnown

The resolver is configured to use the name server (and only that name server). nslookup tries valiantly to contact it but times out, prints "UnKnown" for the default server, and gives you a prompt. You can't really do anything productive without changing servers at this point?after all, no server is running at that IP address?but at least you've got a prompt.

Occasionally you'll see timeouts during the course of an nslookup session. If you are looking up some remote information, the name server could fail to respond because it is still trying to look up the item and nslookup gave up waiting. How can you tell the difference between a name server that isn't running and a name server that is running but didn't respond? nslookup's responses point out the difference. In this case, the response indicates no name server process is running:

C:\> nslookup
Default Server:
*** can't find No response from server

The "No response from server" message is quite misleading because nslookup actually did get a response from the server. What actually happened was this: nslookup sent a DNS query in a UDP packet addressed to port 53 on terminator. Since no name server was running on terminator, there was no process listening on UDP port 53 and the TCP/IP software on terminator responded with an ICMP destination port unreachable message. nslookup received this response and printed the misleading message shown previously.

If a name server is simply not responding, you'll see the following timeout message:

C:\> nslookup
Default Server:
DNS request timed out.
timeout was 2 seconds.
*** Request to timed-out
Query Refused

You generally see a "query refused" error message under two conditions. The first is when you attempt a zone transfer and the server refuses for security reasons (for example, based on the settings in the Zone Transfers tab of the zone properties window). This is what you'll see:

C:\> nslookup
Default Server:
> ls This attempts a zone transfer
*** Can't list domain Query refused
The DNS server refused to transfer the zone to your computer. If this
is incorrect, check the zone transfer security settings for on the DNS
server at IP address

You might also see a "query refused" error from a name server running a recent version of BIND, which has the ability to restrict queries to different zones based on the querier's source IP address.

Using dig

That's one way to deal with what's arguably a shortcoming in nslookup. Another is just to chuck nslookup and use dig, the Domain Information Groper (a reverse-engineered acronym if we've ever heard one). dig is a powerful DNS query tool that comes with BIND. Unfortunately, it isn't shipped with Windows Server 2003, but you can get a version of dig that runs on Windows NT, Windows 2000, and Windows Server 2003 from You may also need to download the other DLLs available at Follow the installation instructions in the readme1sttools.txt file and note the Known Problems section of that file. It tells you, for example, that on Windows 2000 and Windows Server 2003, dig can't read the resolver configuration from the Registry, so it has no idea what name servers to query by default. You'll need to create the file %SystemRoot%\system32\drivers\etc\resolv.conf that contains at least one line specifying a name server to query:


Now, all this might seem like a lot of trouble when nslookup is already installed. But for our DNS troubleshooting purposes, we left nslookup in the dust years ago. We hope you'll come to appreciate dig as much as we do.

With dig, you specify all aspects of the query you'd like to send on the command line; there's no interactive mode. You specify the domain name you want to look up as an argument, and the type of query you want to send (e.g., a for address records, mx for MX records) as another argument; the default is to look up address records. You specify the name server you'd like to query after an "@." You can use either a domain name or an IP address to designate a name server.

dig is smart about arguments, too. You can specify the arguments in any order you like, and dig will figure out that mx is probably the type of record, not the domain name, you want to look up.

One major difference between nslookup and dig is that dig doesn't apply the search list so always give dig fully qualified domain names as arguments. So:

C:\> dig

looks up address records for using the first name server in resolv.conf, while:

C:\> dig mx

looks up MX records for on the same name server, and:

C:\> dig soa

queries for the SOA record of

dig's Output Format

dig shows you the complete DNS response message in all its glory with the various sections (header, question, answer, authority, and additional) clearly called out, and with resource records in those sections printed in master file format. This can come in handy if you need to use some of your troubleshooting tool's output in a zone datafile or in your root hints file. For example, the output produced by:

C:\> dig ns .

looks like this:

; <<>> DiG 8.4 <<>> ns .
; (1 server found)
;; res options: init recurs defnam dnsrch
;; got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 13297
;; flags: qr aa rd; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 13
;; ., type = NS, class = IN
;; Total query time: 0 msec
;; FROM: typhoon to SERVER:
;; WHEN: Tue Aug 12 14:48:50 2003
;; MSG SIZE sent: 17 rcvd: 436

Let's examine this output section by section.

The first line, beginning with the master file comment character (;) and <<>> DiG 8.4 <<>>, simply parrots the options we specified in the command line, namely, that we were interested in the NS records that had for the root zone.

The next line, (1 server found), tells us that when dig looked up the addresses associated with the domain name we specified after the "@,", it found one. (If dig finds more than three, the maximum number of name servers most resolvers can query, it'll report three.)

The line beginning with ->> HEADER <<- is the first part of the header of the reply message that dig received from the remote name server. The opcode in the header is always QUERY, just as it is with nslookup. The status is NOERROR; it can be any of the statuses mentioned earlier in this chapter. The ID is the message ID, a 16-bit number used to match responses to queries.

The flags tell us a bit more about the response. qr indicates that the message was a response, not a query. dig decodes responses, not queries, so qr will always be present. Not so with aa or rd, though. aa indicates that the response was authoritative, and rd indicates that the recursion desired bit was set in the query (since the responding name server just copies the bit from the query to the response). Most of the time rd is set in the query, you'll also see ra set in the response, indicating that recursion was available from the remote name server. However, is a root name server and has recursion disabled, so it handles recursive queries the same as it does iterative queries. So it ignores the rd bit and correctly indicates that recursion wasn't available by leaving ra unset.

The last fields in the header indicate that dig asked one question and received 13 records in the answer section, zero records in the authority section, and 13 records in the additional data section.

The line after the line that contains QUERY SECTION shows us the query dig sent: for the NS records in the IN class for the root zone. After ANSWER SECTION, we see the 13 NS records for the root name servers, and after ADDITIONAL SECTION, we have the 13 A records that correspond to those 13 root name servers. If the response had included an authority section, we'd have seen that, too, after AUTHORITY SECTION.

At the very end, dig includes summary information about the query and response. The first line shows you how long it took the remote name server to return the response after dig sent the query. The second line shows you from which host you sent the query and to which name server you sent it. The third line is a timestamp showing when the response was received. And the fourth line shows you the size of the query and the response, in bytes.

Zone Transfers with dig

As with nslookup, you can use dig to initiate zone transfers. Unlike nslookup, though, dig has no special command to request a zone transfer. Instead, you simply specify axfr (as the query type) and the domain name of the zone as arguments. Remember that you can only transfer a zone from a name server that's authoritative for the zone.

So to transfer the zone from, you could use:

C:\> dig axfr
; <<>> DiG 8.4 <<>> axfr
; (1 server found)
@ 1D IN SOA terminator al.robocop (
2000091402 ; serial
3H ; refresh
1H ; retry
1W ; expiry
1H ) ; minimum
1D IN NS terminator
1D IN NS wormhole
1D IN NS outland.fx
outland.fx 1D IN A
wormhole 1D IN A
wh249 1D IN A
robocop 1D IN A
bigt 1D IN CNAME terminator
cujo 1D IN TXT "Location:" "machine" "room" "dog" "house"
wh253 1D IN A
wh 1D IN CNAME wormhole
shining 1D IN A
terminator 1D IN A
localhost 1D IN A
fx 1D IN NS bladerunner.fx
bladerunner.fx 1D IN A
fx 1D IN NS outland.fx
outland.fx 1D IN A
dh 1D IN CNAME diehard
carrie 1D IN A
diehard 1D IN A
misery 1D IN A
@ 1D IN SOA terminator al.robocop (
2000091402 ; serial
3H ; refresh
1H ; retry
1W ; expiry
1H ) ; minimum
;; Received 25 answers (25 records).
;; WHEN: Tue Aug 12 14:50:03 2003

Note that as with nslookup, the SOA record appears twice, at the beginning and the end of the zone.

dig Options

There are too many dig command-line options to show here, so look at dig's manual page for an exhaustive list. Here's a list of the most important ones, though, and what they do:

-x addressnslookup is smart enough to recognize an IP address and look up the appropriate domain name in, so why not dig? If you use the -x option, dig assumes that the domain name argument you've specified is really an IP address, so it inverts the octets and tacks on Using -x also changes the default record type looked up to ANY, so you can reverse map an IP address with dig -x
-p portSend queries to the specified port instead of port 53, the default.
+norec[urse]Turn off recursion (recursion is on by default).
+vcSend TCP-based queries (queries are UDP by default).

About the Author

dwirch has posted a total of 185 articles.

You can find more information from dwirch by visiting

Comments On This Post

No comments on this post yet!

Do you have a thought relating to this post? You can post your comment here. If you have an unrelated question, you can use the Q&A section to ask it.

Or you can drop a note to the administrators if you're not sure where you should post.

Your IP address is:

Before you can post, you need to prove you are human. If you log in, this test goes away.

Recent Forum Posts

Advanced search added
dwirch posted on September 23, 2017 at about 13:44 in Site News

Job Spammer: Gaurav Mehta - AgreeYa Solutions
dwirch posted on September 22, 2017 at about 10:35 in Spammers

Job Spammer: Prutha Siri - Javelin Systems
dwirch posted on September 10, 2017 at about 6:15 in Spammers

New security implemented
dwirch posted on September 7, 2017 at about 7:16 in Site News

Malicious IP Checker Companion Tool
dwirch posted on August 12, 2017 at about 20:24 in Site News

Job Spammer: Steve Adams
dwirch posted on August 8, 2017 at about 7:44 in Spammers