DEV Community

AdminPackStudio
AdminPackStudio

Posted on

Windows DNS Server Not Resolving External Names: A Read-First Forwarder, Root Hints, and Recursion Triage

Helpdesk: "Since the firewall cutover on Friday, intranet sites open fine but external sites fail or take ten seconds, and nslookup on a PC says 'DNS request timed out' and then works on the second try. The Dallas office also can't reach the partner portal at portal.fabrikam.com, but head office can. A forum post says to point every PC at a public resolver, add five more public DNS servers as forwarders on the DCs, and restart the DNS Server service on all of them. Can we do that?"

Not yet. "DNS not resolving external names" is almost never the client. Your domain controllers answer internal names from their own zones; external names depend on a chain the client never sees: recursion allowed on the server, a forwarder that answers inside the timeout, root hints the server can actually reach as a fallback, a conditional forwarder that exists on the DC the client asked, and a network that passes DNS over UDP and TCP 53. Microsoft describes the end of that chain plainly: "If the server configuration disables recursion, the server normally returns REFUSED for a query that requires recursion. If recursive processing can't complete, the server returns SERVFAIL." And the part most fixes miss: "An unresponsive forwarder doesn't guarantee that the server reaches root hint fallback." Pointing PCs at a public resolver breaks Active Directory lookups, five more forwarders can't all be reached in the default timeout, and a service restart clears the cache and the forwarder state you need to read. Work through it as a chain: which client, which DNS server, which name, which error → is the client asking the server you think? → does the server resolve it itself, and is recursion allowed? → which path does the server pick for this name? → do the forwarders answer, inside the timeout? → can root hints fallback actually happen? → does the conditional forwarder exist on this DC, and do its targets answer? → is a cached answer hiding the fix? → is the network dropping large or TCP DNS? Resolve-DnsName, Get-DnsServerForwarder, Get-DnsServerRecursion, Get-DnsServerZone, Get-DnsServerRootHint, Test-DnsServer, Show-DnsServerCache, and nslookup are the sources for that chain. Change the forwarders first and you'll never know which one was dead.

If external lookups fail from domain controllers at boot and Netlogon logs 5719, Netlogon Event ID 5719 covers the DC locator side. If records go missing from your internal zones, DNS Scavenging Not Working covers aging. This post covers "a Windows DNS server (usually a domain controller) resolves internal names but not internet names, resolves them slowly or only on retry, or can't resolve one partner or cloud namespace through a conditional forwarder, and you need a read-first path before you change client DNS settings, forwarders, root hints, timeouts, or recursion."

TL;DR

  • Prove the server, not the client. Microsoft: "Check whether the resolution fails from the DNS server itself. If so, you can rule out any issue with the client or the network between the client and the DNS server." (Step 3).
  • The server picks one path per name. Hosted zone or cache first, then a matching conditional forwarder, a delegation, the server-level forwarders, and root hints last (Step 4).
  • Dead forwarders cost seconds each. Microsoft: "with default settings, a Windows DNS server will be able to query at most three forwarders." (Step 5).
  • Root hints are a fallback only if the clock and the firewall allow it. Microsoft: "If the overall recursion timeout expires first, the query fails without reaching the root hints." (Step 6).
  • Conditional forwarders are zones, and zones have a replication scope. One stored in the registry of DC1 doesn't exist on DC2 (Step 7).
  • A negative answer can outlive the fix. Clear the cache once, after the fix, not as the fix (Step 8).

Where in the chain did it break?

Step What should be true Typical symptom when it breaks
1. Symptom captured Which client, which DNS server, which name, which error, since when "DNS is down" with no server or name written down
2. Client points at the right server The client asks your internal DNS server, and gets the same answer you get Works from your PC, fails from theirs; nslookup works, the browser doesn't
3. Server resolves, recursion allowed The DNS server resolves the name when asked directly "Query refused", or failure from the DC itself
4. Resolution path You know whether a zone, conditional forwarder, delegation, forwarder, or root hint handles the name An internal zone answers for an external name
5. Forwarders Each forwarder answers fast enough, and the list fits the timeout "Server failure" after 8-12 seconds, slow first lookups
6. Root hints fallback Root hints are present, allowed, and reachable Forwarders down and nothing falls back
7. Conditional forwarder It exists on every DC that needs it, and its targets answer One partner domain fails from one site
8. Cache No stale negative answer on the server or the client Works after clearing the cache, breaks again later
9. Network UDP and TCP 53 pass both ways, including large responses Most names work, a few domains never do
10. Change Only after Steps 1-9 agree: one link, one change Five new forwarders, same failure

Step 1: Capture the symptom (read-only)

Write these on the ticket first:

Fact Why it matters
Which client One PC, one site, one VLAN, every client, or the DNS server itself. Microsoft's first questions are "Check whether all clients are facing the issue or only specific ones are." and whether the failing names are internal or external
Which DNS server it asked The IP address in the client's DNS settings, not the one you assume. A site may use its own DC (Step 2)
Which name and record type An internet name, a partner or cloud namespace (Step 7), or a name inside your own zone name (Step 4)
Exact error text nslookup's "timed out", "Server failure", "Refused", or "Nonexistent domain", or Resolve-DnsName's error. Each points at a different link
Slow or failed A 3-12 second delay that eventually works is a timeout pattern (Step 5); an instant failure is an answer (Steps 3, 4, 7)
Since when, and what changed A firewall or ISP change, a new public IP, a new forwarder, a new DC, a DNS policy, a Windows Server upgrade

Then branch on what you see:

What you see What it usually means (our reading unless noted) Start at
Internal names also fail, or every query to the DC times out The client doesn't reach that DNS server, or the DNS service isn't answering Steps 2 and 3
nslookup works, ping or the browser fails The client's cache, hosts file, or suffix search, not the server Step 2
"Refused" or "Query refused" Recursion is disabled, or a DNS policy denies the query Step 3
An external name under your internal domain name fails Your internal zone answers for it authoritatively Step 4
External names fail with "Server failure" after several seconds, or work on retry A forwarder is dead or slow, and the timeout runs out Step 5
Forwarders are unreachable and nothing falls back Root hints disabled, empty, or blocked Step 6
One partner or cloud namespace fails, the internet is fine The conditional forwarder, its replication scope, or its targets Step 7
Works on DC1, fails on DC2 Different forwarders, a conditional forwarder missing on DC2 Steps 5 and 7
Fails, works after clearing the server cache, fails again later A negative answer cached on the server Step 8
Most names work, a few specific domains never resolve Large UDP responses or TCP 53 dropped Step 9

Step 2: Is the client asking the server you think? (read-only)

Microsoft's client checklist starts with the configuration: run ipconfig /all and "Check the DNS servers that are listed in the output, and verify that the IP addresses listed are correct." On the failing client:

# Read-only. On the failing client: which DNS servers does each adapter use?
Get-DnsClientServerAddress -AddressFamily IPv4 | Where-Object { $_.ServerAddresses } |
  Select-Object InterfaceAlias, ServerAddresses | Format-Table -AutoSize

# Ask each internal DNS server directly, DNS protocol only, hosts file skipped (addresses are examples)
Resolve-DnsName -Name www.microsoft.com -Server 10.0.0.10 -DnsOnly -NoHostsFile
Resolve-DnsName -Name www.microsoft.com -Server 10.20.0.10 -DnsOnly -NoHostsFile

# What the client has cached for the name right now
Get-DnsClientCache -Entry www.microsoft.com -ErrorAction SilentlyContinue
Enter fullscreen mode Exit fullscreen mode

-Server is documented as "Specifies the IP addresses or host names of the DNS servers to be queried." and without it "the interface DNS servers are queried". So a lookup that works with -Server and fails without it says the client is asking someone else.

Why nslookup and the browser disagree: Microsoft notes that "Because nslookup doesn't use the client's DNS cache, name resolution will use the client's configured DNS server." Ping and browsers go through the DNS Client service, which checks its cache first, and that cache is preloaded from the hosts file: "If a Hosts file is configured locally, any host name-to-address mappings from that file are loaded into the cache when the DNS Client service is started."

Finding What it means (our reading unless noted) Next
The client lists a router, a public resolver, or an old DC It isn't asking your internal DNS server. Microsoft: "Run ipconfig /all on the client and confirm the correct DNS server IP is configured." Fix the DHCP scope option or static setting (Step 10); for DHCP, Windows Server DHCP Not Assigning IP Addresses covers scope options
Resolve-DnsName -Server works for one DC and fails for another The DNS servers differ Step 3 on the failing one
Every query to the DC times out, internal names too The client doesn't reach the DNS service. Microsoft: "Ensure that UDP port 53 communication between the client and the DNS server is allowed." Step 3 (service, listening address), then the network path
nslookup works, ping or the browser fails A hosts file entry, a cached negative answer, or a short name with the wrong suffix Read the cache and hosts file; Step 8 for the cache
The same failure from every client and from the DNS server itself Server side Step 3

Step 3: Does the DNS server resolve it itself, and is recursion allowed? (read-only)

Microsoft's server checklist runs the same lookup against the server's own address: nslookup <name> <IP address of the DNS server>, and "If you get a failure or time-out response, see Checking for recursion problems." On the DNS server:

# Read-only. On the DNS server: resolve through itself, on the address clients use (example address)
Resolve-DnsName -Name www.microsoft.com -Server 10.0.0.10 -DnsOnly -NoHostsFile
Get-Service -Name DNS

# Recursion: the server-wide setting, recursion scopes, and any query resolution policies
Get-DnsServerRecursion
Get-DnsServerRecursionScope
Get-DnsServerQueryResolutionPolicy | Format-List *

# Which addresses the service listens on
Get-DnsServerSetting -All | Select-Object ListeningIPAddress, AllIPAddress
Enter fullscreen mode Exit fullscreen mode
# Read-only. On the DNS server: recent errors and warnings in the DNS Server log
Get-WinEvent -FilterHashtable @{ LogName = 'DNS Server'; Level = 2, 3; StartTime = (Get-Date).AddDays(-2) } -MaxEvents 30 -ErrorAction SilentlyContinue |
  Select-Object TimeCreated, Id, Message | Format-List
Enter fullscreen mode Exit fullscreen mode

Microsoft's recursion cmdlet defines the term: "Recursion occurs when a DNS server queries other DNS servers on behalf of a requesting client, and then sends the answer back to the client." Recursion scopes are the newer layer on top: "The legacy recursion setting and list of forwarders are referred to as the default recursion scope." That default scope is named with a single dot, and a policy can send some queries to a different scope.

Finding What it means (Microsoft unless noted) Next
nslookup returns Refused, and Get-DnsServerRecursion shows recursion disabled "If the server configuration disables recursion, the server normally returns REFUSED for a query that requires recursion." Step 10 (only on an internal-only server)
The dot scope has EnableRecursion False, and a policy points internal clients at another scope Selective recursion. Queries that don't match the policy (a new subnet, a new interface) get the default: no recursion (our reading) Read the policy criteria against the client's subnet and the server interface
A policy with a Deny action matches the name or record type The server refuses on purpose Find who added it before removing it
The DNS service isn't running Microsoft's forwarder article: "Ensure the DNS server service is running on both the forwarding and forwarder DNS servers" Start it, then read the DNS Server log for why it stopped
The address clients use isn't in ListeningIPAddress "the server might not be listening on the IP address that you used in your nslookup query." Step 10 (Interfaces tab)
Resolves fine on the server, clients fail The path between client and server Back to Step 2
Fails on the server too, with a delay or "Server failure" A recursion problem Step 4

Step 4: Which path does the server pick for this name? (read-only)

This is the step most fixes skip. Microsoft's current forwarding page lists the order a Windows DNS server follows for a recursive query (with the default ForwardDelegations off): local zones and cache, then "Use a matching conditional forwarder.", then "Use an applicable delegation.", then "Use server-level forwarders.", then "Use root hints when the configuration permits." A zone the server hosts wins outright: "If a hosted authoritative zone covers the query, that zone determines the result."

# Read-only. On the DNS server: which hosted zone, conditional forwarder, or root zone matches the failing name? (our form)
$name = 'portal.fabrikam.com'
Get-DnsServerZone | Where-Object { $name -eq $_.ZoneName -or $name -like "*.$($_.ZoneName)" -or $_.ZoneName -eq '.' } |
  Select-Object ZoneName, ZoneType, IsDsIntegrated, IsAutoCreated | Format-Table -AutoSize
Get-DnsServerSetting -All | Select-Object ForwardDelegations
Enter fullscreen mode Exit fullscreen mode

Microsoft's forwarder article starts the same way: Get-DnsServerZone -Name <domainname> to check for a conditional forwarder, then Get-DnsServerForwarder, then Get-DnsServerRootHint. "If none of them are configured, the name resolution is expected to fail."

Finding What it means (Microsoft unless noted) Next
A zone named . (dot) with type Primary The server thinks it's a root server and won't forward or use root hints. Microsoft's DC guidance says that to forward to the internet "you also must delete the root" zone Step 10
A Primary or Secondary zone matches the name (for example your internal contoso.com and the failing name is www.contoso.com) The server answers authoritatively, and a missing record is a final answer: "It doesn't send that query to a conditional forwarder, server-level forwarder, or root hints." Add the record to the internal zone (Step 10)
A zone with type Forwarder matches A conditional forwarder controls this name Step 7
A delegation inside a hosted zone matches The delegated name servers must answer. Microsoft's broken-delegation test walks it with nslookup, set norecursion, and the delegated servers Fix the delegation's NS and glue records
Nothing matches Server-level forwarders, then root hints Steps 5 and 6
ForwardDelegations is True The order above may not apply. Microsoft: "If your environment enables that setting, validate the resulting interaction between delegations and forwarders before relying on this resolution order." Read it before going further

Step 5: Do the forwarders answer, inside the timeout? (read-only)

Read the forwarder list and the two timers that decide how many of them the server ever tries:

# Read-only. On the DNS server: forwarder list, per-forwarder timeout, root-hint fallback, dynamic reordering
Get-DnsServerForwarder
# Overall recursion budget (Timeout) and whether recursion is on
Get-DnsServerRecursion
Enter fullscreen mode Exit fullscreen mode

Then ask each forwarder directly from the DNS server, and time it. This is the test the server itself is making:

# Read-only. From the DNS server: does each forwarder answer, and how fast? (our form)
foreach ($fwd in (Get-DnsServerForwarder).IPAddress) {
  $ip = "$fwd"
  $sw = [System.Diagnostics.Stopwatch]::StartNew()
  $ok = [bool](Resolve-DnsName -Name www.microsoft.com -Server $ip -DnsOnly -QuickTimeout -ErrorAction SilentlyContinue)
  $sw.Stop()
  [pscustomobject]@{ Forwarder = $ip; Answered = $ok; Milliseconds = $sw.ElapsedMilliseconds }
}
# Microsoft's built-in check of the configured forwarders (the address is the DNS server's own)
Test-DnsServer -IPAddress 10.0.0.10 -Context Forwarder
Enter fullscreen mode Exit fullscreen mode

How the timers interact, from Microsoft's timeout article (KB 2834250 in the old numbering): the server queries the first forwarder at 0 seconds, the second "after 3.5 seconds", the third "after 3.5 + 4 = 7.5 seconds", and then "At the eighth second, RecursionTimeout expires". The client gets its answer late: "We'll send the Server Failure response then after 11.5 seconds." Two Microsoft pages disagree on the default per-forwarder timeout (the timeout article says 3 seconds, the Set-DnsServerForwarder reference says "The default value is 5."), so read the value Get-DnsServerForwarder returns rather than trusting either.

Finding What it means (Microsoft unless noted) Next
One forwarder doesn't answer Every query that reaches it waits out its timeout first. Forwarder health is your job: "DNS Server doesn't determine whether an unresponsive forwarder is offline or slow. Monitor forwarder health separately." Remove or replace it (Step 10)
Four or more forwarders "There will not be enough time to arrive to use the fourth forwarder." Keep two or three healthy ones (Step 10)
All answer, but some take over a second "If a forwarder takes more than one second to respond, the server considers the response slow for reordering purposes." Replace the slow one, or look at the path to it
Windows Server 2022 or later, every forwarder failed once (a link outage) and lookups still fail after the link is back "In Windows Server 2022 and later, if none of the forwarders respond, DNS Server uses only the first server in the dynamic list for subsequent queries until the DNS Server service restarts." Step 10 (reordering), not a blind restart
A forwarder answers your direct test with Refused, or with "Nonexistent domain" for a real name A terminal answer, so no fallback: "A DNS response such as NXDOMAIN or NODATA is a valid, terminal response and doesn't normally trigger fallback." An ISP resolver that only serves its own customers refuses queries from a new public IP after a firewall or ISP change (our reading) Replace that forwarder (Step 10)
The forwarder is another internal DNS server Microsoft: "If the server is healthy and can forward queries, repeat this step, and examine the server to which this server forwards queries." Repeat Steps 3-5 there
Every forwarder answers fast from the DNS server Forwarders aren't the problem Steps 7-9

Test-NetConnection -Port 53 proves nothing here: its -Port parameter "Specifies the TCP port number on the remote computer.", and most DNS queries go over UDP (Step 9).


Step 6: Can root hints fallback actually happen? (read-only)

Root hints are the server's way to resolve without forwarders: "Root hints are resource records that identify DNS servers authoritative for the root of a DNS namespace." With forwarders configured, they're only a fallback, and Microsoft lists four conditions for it, including "The UseRootHint setting is $true" and "The server has usable root hint data and network access to the required DNS servers."

# Read-only. On the DNS server: are root hints present, and is fallback allowed?
Get-DnsServerRootHint
(Get-DnsServerForwarder).UseRootHint
# Microsoft's built-in root hints check (the address is the DNS server's own)
Test-DnsServer -IPAddress 10.0.0.10 -Context RootHints
# Can this server reach a root server directly? (198.41.0.4 is a.root-servers.net; take any address from Get-DnsServerRootHint)
Resolve-DnsName -Name '.' -Type NS -Server 198.41.0.4 -DnsOnly -NoRecursion
Enter fullscreen mode Exit fullscreen mode

Microsoft's own root test uses interactive nslookup against the server being examined:

:: Read-only. On the DNS server (Microsoft's form; the address is the DNS server's own)
nslookup
server 10.0.0.10
set q=NS
Enter fullscreen mode Exit fullscreen mode

Per that article, "If the resolver returns the IP address of a root server, you probably have a broken delegation" further down, and a timeout means checking the root hints, the network, or a firewall: "It's also possible that the recursive time-out default is too short."

Finding What it means (Microsoft unless noted) Next
UseRootHint is False and the forwarders are down Failure by design: "the DNS server forwards unresolved queries only to the DNS servers in the forwarders list and does not try iterative queries if the forwarders do not resolve the queries." Fix the forwarders (Step 5), or decide on purpose (Step 10)
No root hints listed Nothing to fall back to, and nothing to start from without forwarders Step 10 (import root hints)
The direct root query times out from the DNS server, forwarders answer The firewall allows DNS out only to the forwarders. Fallback can't work and only adds delay (our reading) Decide: allow it, or set UseRootHint to False on purpose
Root servers answer, forwarders are dead, and the client still gets "Server failure" The timer ran out first: "If the overall recursion timeout expires first, the query fails without reaching the root hints." Fewer, healthy forwarders (Step 10)
Root hints work, no forwarders configured Normal iterative resolution Step 9 if specific domains still fail

Microsoft's design note is worth reading before you change anything: keep fallback "when direct iterative resolution is acceptable" and "Disable it when policy requires all unresolved queries to remain within the forwarding boundary, and enforce the boundary with network controls."


Step 7: Does the conditional forwarder exist on this DC, and do its targets answer? (read-only)

A conditional forwarder is stored as a zone: "DNS Server stores conditional forwarders as forwarder zones." That means it has a storage location and a replication scope, and a DC that doesn't have the zone sends the partner name down the general forwarder path instead. Read it on every DC:

# Read-only. Every DC: is the fabrikam.com conditional forwarder there, and how is it set? (our form)
foreach ($dc in (Get-ADDomainController -Filter *).HostName) {
  Get-DnsServerZone -ComputerName $dc -Name fabrikam.com -ErrorAction SilentlyContinue |
    Select-Object @{ n = 'DC'; e = { $dc } }, ZoneName, ZoneType, IsDsIntegrated, ReplicationScope, MasterServers, ForwarderTimeout, UseRecursion
}
Enter fullscreen mode Exit fullscreen mode
:: Read-only. One DC at a time: list only conditional forwarder zones (dnscmd's /forwarder filter)
dnscmd DC2 /enumzones /forwarder
Enter fullscreen mode Exit fullscreen mode

Then ask each target server directly, from the DC that fails:

# Read-only. From the failing DC: does each conditional forwarder target answer? (addresses are examples)
Resolve-DnsName -Name portal.fabrikam.com -Server 192.0.2.10 -DnsOnly -QuickTimeout
Resolve-DnsName -Name portal.fabrikam.com -Server 192.0.2.11 -DnsOnly -QuickTimeout
Enter fullscreen mode Exit fullscreen mode
Finding What it means (Microsoft unless noted) Next
The zone exists on head-office DCs, not on the Dallas DC Not AD-integrated (for that kind, "The entries are stored in the registry." of one server), or AD-integrated with a scope that doesn't include Dallas. The scopes are Custom, Domain, Forest, and Legacy Step 10 (replication scope)
Present everywhere, the targets time out from Dallas only The VPN or firewall path from that site to the partner's DNS servers (our reading) Fix the path; Step 9 for UDP and TCP
Three or more targets The conditional-forwarder timer defaults to 5 seconds per target, so "a Windows DNS server will be able to query at most two conditional forwarders." Order the healthy ones first (Step 10)
A target answers Refused Microsoft's scenario: a policy on the target refuses the query, and "The DNS server won't contact the second conditional forwarder as we already got a response from the first one" Ask the partner, or check Get-DnsServerQueryResolutionPolicy if it's a Windows server you run
A target answers "Nonexistent domain" for some names only Missing records on the target: "Register the missing records on the forwarder for the zone in question, either statically or dynamically." The partner's zone, not your forwarder
UseRecursion False and the targets are down Failure by design; nothing else is tried Fix the targets
You try to create it and get a zone-exists error "You can't create a conditional forwarder for a DNS name that matches a primary, secondary, or stub zone that the same DNS server hosts." Step 4

Azure private endpoints are a common version of this. Microsoft: "DNS queries for private endpoints must originate from the virtual network that is linked to the private DNS zone." So an on-premises conditional forwarder that points straight at Azure's 168.63.129.16 can't work; it points at a DNS forwarder or Private Resolver inside the linked virtual network, and "The conditional forwarding must be made to the recommended public DNS zone forwarder." (for example the public service zone rather than the privatelink zone).


Step 8: Is a cached answer hiding the fix? (read-only)

Both the DNS server and the client cache negative answers. Read before you clear:

# Read-only. On the DNS server: what's cached for the failing name, and the cache limits
Show-DnsServerCache | Where-Object { $_.HostName -like '*fabrikam*' }
Get-DnsServerCache
Enter fullscreen mode Exit fullscreen mode
# Read-only. On the client: what the DNS Client service has cached for the name
Get-DnsClientCache -Entry portal.fabrikam.com -ErrorAction SilentlyContinue
Enter fullscreen mode Exit fullscreen mode

Get-DnsServerCache returns the limits, including "MaxTTL, MaxNegativeTTL"; Microsoft's example shows a MaxNegativeTTL of 15 minutes, so a negative answer cached before the fix can linger that long (our reading). On the client, Microsoft's check is ipconfig /displaydns: a "Name does not exist" entry means a negative response "was returned from a DNS server and was cached on the client."

Finding What it means (Microsoft unless noted) Next
A negative entry for the name on the server, upstream already fixed It ages out on its own; clearing it once is fine after the fix (Step 10) Clear once, then re-test
Works after Clear-DnsServerCache, then fails again later through a conditional forwarder Microsoft's dual-stack case: a bad AAAA answer from a third-party target "poisons the local DNS server cache and generates a negative cache entry for the host A record, too." Ask the target's vendor; Microsoft's workaround is a recursion policy that denies AAAA queries for that path
A stale positive answer (old IP) on the server The record's TTL hasn't run out Wait it out, or clear once
Negative entry on the client only The client cached a failure from earlier ipconfig /flushdns on that client after the server is fixed

Step 9: Is the network dropping large or TCP DNS? (read-only, then one optional logging change)

DNS uses both transports. Microsoft's port page: "Messages are sent over UDP and DNS servers bind to UDP port 53." When an answer is too big, "The DNS client (message sender) can then choose to reissue the request to the DNS server using TCP (over TCP port 53)." And Windows DNS advertises bigger UDP answers by default through EDNS0, which some firewalls drop: "EDNS0 allows larger User Datagram Protocol (UDP) packet sizes. However, some firewall programs may not allow UDP packets that are larger than 512 bytes."

# Read-only. From the DNS server: the same name over UDP and over TCP to one forwarder (address is an example)
Resolve-DnsName -Name portal.fabrikam.com -Server 203.0.113.53 -DnsOnly
Resolve-DnsName -Name portal.fabrikam.com -Server 203.0.113.53 -DnsOnly -TcpOnly
# The server's EDNS settings
Get-DnsServerEDns
Enter fullscreen mode Exit fullscreen mode

-TcpOnly is documented as "Uses only TCP for this query." Microsoft's symptom for the EDNS case: "After you deploy a Windows-based DNS server, DNS queries to some domains may not be resolved successfully."

To see what the server itself sent and what timed out, the DNS Server analytic log records outbound recursive queries and timeouts (event 260 is RECURSE_QUERY_OUT, 262 is RECURSE_QUERY_TIMEOUT, 258 is RESPONSE_FAILURE). It's off by default; Microsoft's steps turn it on in Event Viewer (Applications and Services Logs → Microsoft → Windows → DNS-Server → View → Show Analytic and Debug Logs → Analytical → Properties → Enable logging). Microsoft's cost note: "There's no apparent performance impact for query rates of 50,000 QPS and lower." Reproduce once, then read it:

# Read-only. On the DNS server: recursive timeouts and response failures from the analytic log (our form; -Oldest is required for analytic logs)
Get-WinEvent -LogName 'Microsoft-Windows-DNSServer/Analytical' -Oldest -ErrorAction SilentlyContinue |
  Where-Object { $_.Id -in 258, 262 } |
  Select-Object -Property TimeCreated, Id, Message -Last 40 | Format-List
Enter fullscreen mode Exit fullscreen mode

-Oldest "is required to get events from .etl and .evt files and from debug and analytic logs." If the read errors while the log is enabled, disable the log first and read it then (our reading of Microsoft's note that a circular log can't be viewed while it's being written).

Finding What it means (Microsoft unless noted) Next
UDP fails, TCP works, for the same name A firewall drops large or EDNS UDP answers. Resolution: "update the firewall program to recognize and allow UDP packets that are larger than 512 bytes." The firewall first; Step 10 has Microsoft's workaround
UDP works, TCP fails TCP 53 blocked; any truncated answer then fails (our reading) Allow TCP 53 between the DNS server and its forwarders
Event 262 with the same Destination again and again That forwarder or target isn't answering Step 5 or 7 for that address
Event 258 for the name Read the Reason and RCODE fields in the message Map it back to Steps 3-7
Both transports fail to every forwarder Outbound DNS from the DNS server is blocked, often after a firewall change (our reading) Allow UDP and TCP 53 from the DNS servers to the forwarders

Common false starts

What people try Why it misleads (our reading unless noted)
Pointing PCs or DCs at a public resolver Internal names and AD records stop resolving. Microsoft: "Don't configure the DNS client settings on the domain controllers to point to DNS servers of your Internet Service Provider (ISP)." Forward from your DNS servers instead; Active Directory Replication Error 1722 shows what that does between DCs
Adding more forwarders Past three, the extras are never reached with default timers (Step 5), and each dead one adds seconds
Restarting the DNS Server service on every DC It clears the cache and, on Windows Server 2022 and later, the stuck forwarder state, so the symptom goes away until the next outage. You lose the evidence of which forwarder failed
Clearing the server cache over and over It hides the pattern that points at negative caching (Step 8)
Test-NetConnection to port 53 It tests TCP only; DNS answers mostly come back over UDP
Pinging the forwarder ICMP can pass while DNS is blocked, and the reverse
Turning on Disable recursion to stop the delays Microsoft notes "This setting also disables forwarders." External names then fail outright with Refused
Raising every timeout to the maximum A dead forwarder now costs more time per query, and clients give up first. Microsoft's own rule: "DNS: The recursion timeout must be greater than the forwarding timeout"
Disabling EDNS before testing UDP against TCP It may work around a firewall bug without telling you which firewall (Step 9)
Recreating a conditional forwarder on one DC Without the right replication scope, the next DC still won't have it (Step 7)

Step 10: Change one link, then prove it

Only after Steps 1-9 agree on which link failed. Write down the current state first: Get-DnsServerForwarder, Get-DnsServerRecursion, Get-DnsServerRootHint, the Step 7 conditional forwarder table, and Get-DnsServerQueryResolutionPolicy from every DNS server (our habit). Set-DnsServerForwarder replaces the whole list: "This cmdlet overwrites existing server level forwarders."

The client asks the wrong server (Step 2). Fix the DHCP scope's DNS server option, or the static setting. Microsoft's command for a static client (interface name and addresses are examples):

# Change. On ONE client: point the adapter at the internal DNS servers (Microsoft's form, two addresses)
Set-DnsClientServerAddress -InterfaceAlias 'Ethernet' -ServerAddresses ('10.20.0.10', '10.0.0.10')
Enter fullscreen mode Exit fullscreen mode

Recursion off, or a policy refusing (Step 3). Turn recursion on only on servers that serve internal clients; Microsoft warns "Allow recursive queries only from trusted clients and networks, and don't expose recursive DNS service to untrusted networks." If selective recursion is by design, fix the policy's subnet or interface criteria instead.

# Change. On an internal-only DNS server: allow recursion
Set-DnsServerRecursion -Enable $true -PassThru
Enter fullscreen mode Exit fullscreen mode

A root zone or an internal zone answering (Step 4). Delete the . zone in DNS Manager under Forward Lookup Zones, per Microsoft's DC guidance. For an external name under your internal zone name, add the record to the internal zone; don't create a conditional forwarder for a name you host.

A dead, slow, or refusing forwarder (Step 5). Replace the list with two or three forwarders you've tested from the DNS server, preferred one first:

# Change. On the DNS server: replace the whole forwarder list (it overwrites; addresses are examples)
Set-DnsServerForwarder -IPAddress 203.0.113.53, 198.51.100.53 -PassThru
# Or remove just the dead one
Remove-DnsServerForwarder -IPAddress 192.0.2.53 -PassThru
Enter fullscreen mode Exit fullscreen mode

On Windows Server 2022 or later, if you want the older behavior of cycling through every forwarder after they've all failed, Microsoft's switch is "To make the server cycle through all configured forwarders as in earlier versions, disable dynamic reordering with Set-DnsServerForwarder -EnableReordering $false." Change timers last, and keep the recursion timeout above the forwarder timeout (Set-DnsServerRecursion -Timeout, Set-DnsServerForwarder -Timeout; both cap at 15 seconds per their references).

Root hints (Step 6). If they're missing, Microsoft's cmdlet copies them from another DNS server: "The root hints that you copy will not overwrite any existing root hints." If policy keeps all lookups inside the forwarders, make that explicit rather than leaving a fallback that can't work:

# Change. On the DNS server: copy root hints from a healthy DNS server (example name), or turn fallback off on purpose
Import-DnsServerRootHint -NameServer dc1.contoso.com -PassThru
Set-DnsServerForwarder -UseRootHint $false -PassThru
Enter fullscreen mode Exit fullscreen mode

The conditional forwarder (Step 7). Store it in AD with a scope that covers every DC that needs it, and list only targets you've tested:

# Change. On one DC: create the forwarder in AD, replicated to every DNS server on a DC in the forest (addresses are examples)
Add-DnsServerConditionalForwarderZone -Name fabrikam.com -ReplicationScope Forest -MasterServers 192.0.2.10, 192.0.2.11 -PassThru
# Or fix an existing one: targets and per-zone timeout
Set-DnsServerConditionalForwarderZone -Name fabrikam.com -MasterServers 192.0.2.10, 192.0.2.11 -ForwarderTimeout 5 -PassThru
Enter fullscreen mode Exit fullscreen mode

If a registry-stored copy already exists on one DC, remove that copy first (export its settings) so the AD-integrated one doesn't collide with it (our reading). Microsoft's forest scope means "Replicate the conditional forwarder to all DNS servers that run on domain controllers in the forest."

Cache (Step 8). Once, after the fix, on the server and then the client:

# Change (low risk). On the DNS server, then on the client that cached the failure
Clear-DnsServerCache -Force
Clear-DnsClientCache
Enter fullscreen mode Exit fullscreen mode

Clear-DnsClientCache is documented as "equivalent to running ipconfig /flushdns."

Large UDP or TCP 53 dropped (Step 9). Fix the firewall. Microsoft's workaround, if you can't yet, turns off EDNS probes on the DNS server (a registry change; reverse it with 1 after the firewall is fixed):

:: Change. On the DNS server: Microsoft's EDNS0 workaround (zero, not the letter O)
dnscmd /config /enableednsprobes 0
Enter fullscreen mode Exit fullscreen mode

Turn the analytic log back off when you're done (our habit).

Then prove it. From a failing client and from each DNS server: Resolve-DnsName -Name www.microsoft.com -Server <each DNS server> -DnsOnly answers in well under a second, the partner name resolves from the Dallas DC as well as head office, Test-DnsServer -Context Forwarder returns Success, and the analytic log shows no new event 262 for your forwarders (our reading). Then let the helpdesk retest the original sites.


When a change is justified

Finding Prefer Avoid
Client asks the wrong server Fix the DHCP option or static setting to internal DNS servers Public resolvers on domain-joined PCs or DCs
Recursion refused Recursion on for internal clients, or a corrected recursion policy An open resolver reachable from the internet
Dead or refusing forwarder Two or three tested forwarders, preferred one first Five more forwarders on top of the dead one
Forwarders fine, fallback broken Root hints reachable, or UseRootHint off on purpose Raising every timeout to 15 seconds
Conditional forwarder missing on one site's DC AD-integrated forwarder with Forest or Domain scope Registry copies created by hand on each DC
Stale negative answer One cache clear after the fix Clearing the cache as the fix
Firewall drops large UDP answers Firewall allows EDNS and TCP 53 EDNS off with no ticket to turn it back on

FAQ

Why is my Windows DNS server not resolving external names?
Most often a forwarder is dead or refusing and the recursion timer runs out before root hints are tried, recursion is disabled or limited by a policy, or an internal zone answers for the name. Microsoft's first split: "Check whether the resolution fails from the DNS server itself." Then read Get-DnsServerForwarder and test each forwarder directly.

Should I use DNS forwarders or root hints?
Either works; forwarders centralize lookups, root hints resolve without them. Microsoft keeps root hints as a fallback by default and says to turn it off "when policy requires all unresolved queries to remain within the forwarding boundary". Don't leave fallback on if the firewall blocks it.

Why is my DNS conditional forwarder not working?
Usually it doesn't exist on the DC the client asked (registry-stored or the wrong replication scope), its targets don't answer from that site, or a target refuses or lacks the record. Run Step 7 on every DC, then query each target directly.

How many DNS forwarders should I configure?
Two or three healthy ones. With default timers, Microsoft says the server can reach "at most three forwarders", and every dead one in front adds seconds to each lookup.

Why does nslookup work but ping doesn't?
nslookup asks the DNS server directly; ping goes through the DNS Client service's cache, which also holds hosts file entries and earlier negative answers. Microsoft: "Because nslookup doesn't use the client's DNS cache, name resolution will use the client's configured DNS server." Check the client cache and hosts file (Steps 2 and 8).


Related posts

Free checklist

Adding five forwarders and restarting DNS on every DC before anyone tested a single forwarder is a change made everywhere at once. So is a Conditional Access policy enforced before anyone read the report-only results. The free Conditional Access pre-enforcement checklist keeps break-glass accounts, pilot groups, and report-only review on one page:

👉 https://cashflow4375.gumroad.com/l/ujkqxb?utm_source=devto&utm_medium=article&utm_campaign=aps_first_sale&utm_content=windows-dns-server-not-resolving-external-names

If you want the rest of the Intune runway written down for the team (enrollment hygiene, compliance phasing, break/fix cards and read-only PowerShell snapshots), the Intune & M365 Admin Starter Pack pairs with this triage: https://cashflow4375.gumroad.com/l/joonf?utm_source=devto&utm_medium=article&utm_campaign=aps_first_sale&utm_content=windows-dns-server-not-resolving-external-names


Admin Pack Studio; not affiliated with Microsoft. Steps 1-9 favor read-only checks: Get-DnsClientServerAddress, Get-DnsClientCache, Resolve-DnsName, Get-Service, Get-DnsServerRecursion, Get-DnsServerRecursionScope, Get-DnsServerQueryResolutionPolicy, Get-DnsServerSetting, Get-DnsServerZone, Get-DnsServerForwarder, Get-DnsServerRootHint, Test-DnsServer, Show-DnsServerCache, Get-DnsServerCache, Get-DnsServerEDns, Get-WinEvent, dnscmd /enumzones, and nslookup. Enabling the analytic log, changing client DNS settings, recursion, forwarders, timeouts, reordering, root hints, conditional forwarders, or EDNS, and clearing caches are deliberate changes. Change one link at a time, test from the failing client and from each DNS server, and check current Microsoft Learn for version-specific behavior.

Top comments (0)