
You just tried to load a page, deploy a service, or hit an API endpoint — and got nothing. The browser says "DNS server not responding." Or maybe your application logs are filled with resolution failures, your monitoring dashboard just lit up, and you're staring at a terminal wondering where to start.
This error means exactly what it sounds like: your machine sent a DNS query to a resolver, and the resolver either didn't answer at all or the response never made it back. The client's stub resolver waited for a reply, hit its timeout window, and gave up. No IP address came back, so the hostname can't be translated, and everything that depends on that name — web requests, API calls, email delivery, authentication flows, database connections using hostnames — stops working.
The tricky part is that "DNS server not responding" is a symptom, not a diagnosis. The actual cause could be anywhere along the path: your local network adapter, your configured resolver, a firewall rule you forgot about, your ISP's DNS infrastructure, or a problem with the domain itself. The error message doesn't tell you which one. That's your job to figure out.
This guide walks you through a structured approach to diagnosing and fixing DNS resolution failures. We'll start with the most common causes and a quick way to map your symptoms to likely culprits. Then we'll work through a step-by-step troubleshooting workflow with copy-ready commands for both Windows and Linux. After that, we'll cover how to use tools like nslookup.io to investigate from outside your network, how to automate DNS checks so you catch problems earlier, and how to verify that your fix actually stuck.
This article is written for IT admins, DevOps engineers, developers, SREs, and MSP technicians — anyone who needs to troubleshoot DNS under pressure and wants a reliable process rather than a random walk through Stack Overflow threads.
Let's get into it.
Before you start running commands, take thirty seconds to characterize the failure. The pattern of what's broken — and what still works — narrows the problem space significantly. A failure that affects every device on your network points somewhere very different than one that only hits a single laptop.
Here's a reference table you can use to match what you're seeing to the most likely cause.
| Symptom | Likely Cause(s) | Quick Check |
|---|---|---|
| All sites fail on one device | Local DNS config, network adapter issue, local firewall/antivirus | Run nslookup google.com on the affected machine |
| All sites fail on all LAN devices | Router DNS proxy failure, ISP DNS outage, upstream resolver down | Test from a phone on cellular data (bypasses the LAN entirely) |
| Only specific domains fail | Stale DNS cache, incomplete propagation, domain-level misconfiguration | Run nslookup failingdomain.com 8.8.8.8 to test against a public resolver |
| Intermittent failures | Overloaded resolver, packet loss on the path to the resolver, flaky upstream | Run repeated queries and ping the resolver IP to check for drops |
| Failure only when connected to VPN | VPN DNS override, split-tunnel misconfiguration, VPN DNS server unreachable | Disconnect the VPN and retest immediately |
| Works in the browser but fails in CLI (or vice versa) | Browser using DNS-over-HTTPS (DoH), different resolver paths for different apps | Compare dig output to what the browser resolves in DevTools |
| Failure after a recent DNS change | Propagation delay, old record cached with a long TTL, wrong record published | Query authoritative nameservers directly with dig @ns1.example.com domain.com |
| Failure only on internal/private domains | Internal DNS server down, VPN required for access, split-horizon DNS issue | Check if internal resolver is reachable and responding |
Now let's walk through each category in more detail.
This is the most common cause for single-device failures. Your network adapter might have lost its IP configuration, the DNS server addresses assigned via DHCP could be stale or wrong, or the adapter itself might be in a bad state. On Windows, this often happens after waking from sleep, switching between Wi-Fi and Ethernet, or after a Windows Update.
Check your adapter status first. If your machine doesn't have a valid IP address or default gateway, DNS is the least of your problems — you have a layer 3 connectivity issue.
If every device on your network fails to resolve, and the issue goes away when you switch to your phone's cellular connection, your ISP's DNS resolvers are likely the problem. ISP-provided DNS servers go down more often than most people realize, and they can also become overloaded during peak usage. Some ISPs also filter or redirect certain queries, which can produce confusing partial failures.
The quickest workaround is switching to a public resolver like Google (8.8.8.8, 8.8.4.4), Cloudflare (1.1.1.1, 1.0.0.1), or Quad9 (9.9.9.9). But read the production safety note in the Quick Fix vs. Deep Fix section below before doing this on anything important.
Firewalls and security software can block DNS traffic without obvious warnings. DNS uses UDP port 53 by default (and TCP 53 for larger responses or zone transfers), and some firewalls have rules that interfere with this — particularly host-based firewalls like Windows Defender Firewall or iptables/nftables rules on Linux.
VPNs are another frequent offender. Most VPN clients override your DNS settings when connected, routing queries through the VPN tunnel to a DNS server on the other side. If that server is unreachable, misconfigured, or slow, your DNS breaks. Split-tunnel VPN configurations are especially tricky because some queries go through the VPN and others don't, leading to partial failures that are hard to reproduce.
Antivirus software with "web protection" or "DNS filtering" features can also intercept and modify DNS queries. If you've recently installed or updated security software, that's a strong lead.
In many home and small-business networks, the router acts as a DNS proxy. Devices on the network use the router's LAN IP (often 192.168.1.1) as their DNS server, and the router forwards those queries to the actual upstream resolvers. If the router's DNS proxy service hangs, crashes, or loses its upstream configuration, every device on the network loses DNS — even though the router itself might still pass traffic fine at the IP level.
Rebooting the router fixes this surprisingly often. But if the problem recurs, you may need to check the router's DNS settings, update its firmware, or configure your devices to use a public resolver directly instead of relying on the router as a middleman.
Sometimes the problem is simply that your machine is pointed at the wrong DNS server. Maybe someone hardcoded a DNS address that's since been decommissioned. Maybe a DHCP lease handed out a server that's only reachable from a different subnet. Maybe /etc/resolv.conf was overwritten by a script or a container runtime.
On Linux, the situation is complicated by the fact that multiple systems can manage /etc/resolv.conf — systemd-resolved, NetworkManager, resolvconf, or manual edits. They don't always agree, and it's possible to end up with a configuration that looks correct in one place but is actually being overridden by another.
If you recently changed a DNS record and the old value is still showing up, you're probably dealing with caching. DNS is designed to be cached aggressively — that's what TTLs (Time To Live) are for. When you update a record, the old value can persist in resolvers' caches until the TTL expires. If you set a 24-hour TTL, some resolvers might serve the old record for up to 24 hours.
Flushing your local cache helps for your own machine, but it doesn't clear the caches of intermediate resolvers between you and the authoritative nameserver. This is why post-change DNS validation across multiple resolvers and regions matters — and it's one of the places where a tool like nslookup.io is particularly useful.
Sometimes your configured resolver is reachable but can't answer your query because its own upstream sources are failing. Recursive resolvers depend on being able to reach root servers, TLD servers, and authoritative nameservers for the domains you're querying. If any of those are unreachable from the resolver's perspective — due to network issues, DDoS attacks, or misconfigurations — the resolver will eventually time out and return a SERVFAIL or simply not respond.
This is harder to diagnose from the client side because the failure looks the same as a dead resolver. Testing against multiple independent resolvers is the key differentiator: if Google DNS, Cloudflare, and Quad9 all fail for the same domain, the problem is likely upstream (at the authoritative nameserver level). If only one resolver fails, the problem is with that resolver.
Some resolvers — particularly enterprise DNS firewalls and security-focused resolvers like Quad9 — block queries to domains flagged as malicious. If you're trying to resolve a domain that's been flagged (correctly or incorrectly), you'll get an NXDOMAIN or a refused response that looks a lot like "DNS server not responding" to the end user.
Similarly, DNS rebinding protection (common in routers and some resolvers) blocks DNS responses that point to private IP ranges (like 192.168.x.x or 10.x.x.x). This is a security feature, but it can break legitimate use cases like local development environments or IoT device management interfaces.
When you're troubleshooting under pressure, a linear checklist can be slower than a branching decision tree. Here's a tree that takes you from the error to the most likely cause in a few steps.
Start here:
1. Can you ping the DNS server's IP address?
For example, run ping 8.8.8.8 or ping the IP shown in your DNS configuration.
→ NO: You have a network connectivity issue, not a DNS issue (yet). Check your network adapter status, verify you have a valid IP address and default gateway, and make sure no firewall is blocking outbound ICMP or UDP traffic. If you can't reach any external IP, the problem is at the network layer. Skip to Step 1 and Step 5 in the troubleshooting workflow.
→ YES: Move to question 2.
2. Can you resolve a domain using a public DNS server directly?
Run nslookup google.com 8.8.8.8 or dig @1.1.1.1 google.com.
→ NO: The public resolver isn't answering you, or something is blocking DNS traffic specifically. This usually means a firewall is blocking outbound UDP/TCP port 53, or there's a transparent DNS proxy intercepting your queries. Check firewall rules and VPN settings. See Step 6 in the troubleshooting workflow.
→ YES: Move to question 3.
3. Can you resolve the same domain using your configured (default) DNS server?
Run nslookup google.com with no server argument (uses your default resolver).
→ NO: Your configured DNS server is the problem. It's either unreachable, overloaded, or misconfigured. Check which server your system is using (Step 2), then consider switching to a public resolver as a workaround while you investigate the configured one. See Steps 2 and 3.
→ YES: Move to question 4.
4. Is the failure limited to a specific domain (or small set of domains)?
Try resolving several different domains. Do most work, with only one or a few failing?
→ YES: The issue is domain-specific.
Check whether the domain's DNS records were recently changed (propagation delay), whether the domain's authoritative nameservers are responding, and whether the domain exists at all (NXDOMAIN). Use dig specificdomain.com +trace to trace the resolution path, and check nslookup.io for a multi-resolver view. See Step 8.
→ NO: General resolution is failing for your configured resolver. If public resolvers work but your configured resolver fails across multiple domains, the resolver itself is the issue — it may be down, overloaded, or misconfigured. Check with your ISP, sysadmin, or whoever manages the resolver. See Step 9.
5. Does the problem persist after flushing the DNS cache?
Flush your local cache (Step 4) and retest.
→ YES: The problem is upstream — not a stale local cache. Continue investigating the resolver or the domain's authoritative infrastructure.
→ NO: The stale cache was the issue. Monitor for recurrence, and check TTL values on the records in question.
This tree covers roughly 90% of DNS-not-responding scenarios. For the remaining edge cases — split-horizon DNS, DNSSEC validation failures, EDNS issues — you'll need more specialized investigation, but the tree gets you to the right neighborhood fast.
Not every DNS problem needs a deep investigation. Sometimes you need the service back up in the next sixty seconds and you'll do the postmortem later. Other times, the quick fix is just masking a real problem that'll bite you again.
Here's how to think about it for each common cause.
If you're troubleshooting DNS on a production system, be cautious with changes to /etc/resolv.conf, DHCP-assigned DNS servers, or upstream resolver configurations. Switching DNS resolvers can change how traffic is routed, affect CDN performance (many CDNs use the resolver's IP for geographic routing decisions), and break split-horizon DNS setups where internal and external names resolve differently. In production environments, test changes on a single host first. Document the current configuration before you change anything. If you're an MSP or you're touching a system you don't own, communicate changes before making them.
Quick fix: Flush the local DNS cache.
# Windows
ipconfig /flushdns
# Linux (systemd-resolved)
resolvectl flush-caches
# macOS
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
Deep fix: Investigate why the stale record was cached. Check TTL values on the DNS records — if they're set very high (86400 seconds = 24 hours), consider lowering them before making future changes. If you're about to do a DNS migration, lower TTLs 24–48 hours in advance so the old records expire faster.
When to escalate: If flushing the cache doesn't help, the stale data is in an upstream resolver's cache, not yours. You'll need to wait for the TTL to expire or contact the resolver operator.
Quick fix: Temporarily switch to a known-good public resolver, but do it in a way your OS actually manages.
# Linux (systemd-resolved) — temporary test on a single interface
sudo resolvectl dns eth0 8.8.8.8 8.8.4.4
# Linux (NetworkManager)
sudo nmcli con mod "Wired connection 1" ipv4.dns "8.8.8.8 8.8.4.4"
sudo nmcli con up "Wired connection 1"
# Windows — set via PowerShell (replace "Ethernet" with your adapter name)
Set-DnsClientServerAddress -InterfaceAlias "Ethernet" -ServerAddresses ("8.8.8.8","8.8.4.4")
Use direct edits to /etc/resolv.conf only as a short-lived emergency test, because many systems overwrite that file automatically.
Deep fix: Determine why the original DNS server is unreachable. Is it decommissioned? Overloaded? Firewalled? Is DHCP handing out the wrong address? Fix the root cause and restore the correct resolver configuration.
When to escalate: If the DNS server belongs to your ISP or a third party and it's consistently slow or unreliable, it may be time to move to a managed DNS resolver or run your own caching resolver (like Unbound or dnsmasq) in front of it.
Quick fix: Restart the network adapter.
# Windows (PowerShell, admin)
Restart-NetAdapter -Name "Wi-Fi"
# Linux
sudo ip link set eth0 down && sudo ip link set eth0 up
# or
sudo nmcli device disconnect eth0 && sudo nmcli device connect eth0
Deep fix: Check for driver issues, DHCP lease problems, or conflicting network configurations. On Windows, run ipconfig /all and verify that the adapter has a valid IP, subnet mask, default gateway, and DNS server. On Linux, check ip addr and resolvectl status.
When to escalate: If the adapter repeatedly loses its configuration, you may have a hardware issue, a driver bug, or a conflict with power management settings (common with Wi-Fi adapters that get disabled during sleep).
Quick fix: Disconnect the VPN and retest. If DNS works without the VPN, the VPN configuration is the problem.
Deep fix: Review the VPN's DNS settings. Most VPN clients push a DNS server to the client when connected. If that server is unreachable or slow, configure the VPN to use a reachable DNS server. For split-tunnel setups, make sure DNS queries for internal domains go through the tunnel while external queries use the regular resolver.
When to escalate: If the VPN is managed by another team or vendor, provide them with the specific DNS failures you're seeing (resolver IP, query, expected result, actual result) so they can adjust the VPN DNS configuration.
Quick fix: Reboot the router. If that doesn't work, configure devices to use a public resolver directly instead of the router's IP.
Deep fix: Check the router's firmware version and DNS proxy settings. Some consumer routers have known bugs in their DNS proxy implementations. Consider disabling the DNS proxy and configuring the router's DHCP server to hand out public resolver IPs directly.
When to escalate: If the router is provided by your ISP and you can't change its settings, contact the ISP. If it's your own equipment and the firmware is current, the router may need to be replaced.
This is the core section. Work through these steps in order — each one builds on the previous, and skipping ahead often wastes time.
Before you go deep on DNS troubleshooting, confirm that DNS is actually the problem. If your network connection is down entirely, fixing DNS won't help.
Test basic network connectivity:
# Both Windows and Linux
ping 8.8.8.8
If this succeeds (you get replies), your machine can reach the internet at the IP level. If it fails, your problem is network connectivity, not DNS — check your adapter, cable/Wi-Fi, gateway, and firewall.
Test DNS resolution:
# Windows
nslookup google.com
# Linux
dig google.com
# or
nslookup google.com
If ping 8.8.8.8 works but nslookup google.com fails, you've confirmed a DNS-specific problem. Proceed to Step 2.
If both fail, start with the network connectivity issue. DNS troubleshooting can wait.
What the output looks like when DNS fails:
# Windows nslookup failure
DNS request timed out.
timeout was 2 seconds.
Server: UnKnown
Address: 192.168.1.1
DNS request timed out.
timeout was 2 seconds.
*** Request to UnKnown timed-out
# Linux dig failure
;; connection timed out; no servers could be reached
The key phrase is "timed out" — your client sent the query and got no response within the timeout window.
You need to know which DNS server your machine is actually using. This isn't always obvious, especially on Linux where multiple systems can manage the resolver configuration.
Windows:
ipconfig /all
Look for the "DNS Servers" line under your active network adapter. You'll see one or more IP addresses. Common values include your router's IP (192.168.1.1), your ISP's DNS servers, or public resolvers if someone configured them manually.
# More targeted — shows just DNS for each adapter
Get-DnsClientServerAddress
Linux (systemd-resolved):
resolvectl status
This shows the DNS servers configured for each network interface, along with the current DNS settings and whether DNSSEC or DNS-over-TLS is enabled.
# If resolvectl isn't available
cat /etc/resolv.conf
On systems using systemd-resolved, /etc/resolv.conf often points to 127.0.0.53 (the local stub resolver). The actual upstream servers are configured in systemd-resolved, not in the file itself. Don't be fooled by this.
# Check who manages resolv.conf
ls -la /etc/resolv.conf
If it's a symlink (e.g., to /run/systemd/resolve/stub-resolv.conf), systemd-resolved is managing it. If it's a regular file, something else is in control.
What to look for:
Write down the DNS server IP(s) — you'll need them for the next steps.
This step isolates whether the problem is with your configured resolver or with the domain/network path.
Windows:
nslookup google.com 8.8.8.8
nslookup google.com 1.1.1.1
Linux:
dig @8.8.8.8 google.com
dig @1.1.1.1 google.com
Interpreting the results:
Both public resolvers work: Your network is fine, and the problem is with your configured DNS server. It's either down, unreachable from your machine, or misbehaving. Jump to Step 5 to try restarting the DNS client, or switch to a public resolver as a temporary workaround.
Public resolvers also fail: Either something is blocking DNS traffic specifically (firewall, proxy, VPN), or you have a connectivity issue that ping 8.8.8.8 didn't catch (some networks allow ICMP but block UDP 53). Jump to Step 6.
Public resolvers work for some domains but not the one you care about: The issue is domain-specific. Jump to Step 8.
Checking response times:
# Linux — dig shows query time
dig @8.8.8.8 example.com | grep "Query time"
;; Query time: 23 msec
# If the query time is >500ms or wildly inconsistent, the resolver
# or the path to it may be overloaded
If you're getting stale results or if a recent DNS change hasn't taken effect on your machine, flushing the local cache is the right first step.
Windows:
ipconfig /flushdns
Expected output:
Windows IP Configuration
Successfully flushed the DNS Resolver Cache.
You can verify the cache is empty:
# Show current cache contents (before/after flush)
Get-DnsClientCache
Linux (systemd-resolved):
# Flush the cache
resolvectl flush-caches
# Verify it's empty
resolvectl statistics
The "Current Cache Size" should drop to 0 (or close to it) immediately after flushing.
# Older systems or alternate method
sudo systemd-resolve --flush-caches
macOS:
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
After flushing, retest immediately:
nslookup example.com
If the problem was a stale cached record, this should fix it. If not, the stale data isn't in your local cache — it's in an upstream resolver's cache, and you'll need to wait for the TTL to expire or test against a resolver that doesn't have the stale record cached.
Sometimes the DNS client service or the network adapter gets into a bad state. Restarting them is low-risk and often effective.
Windows — restart the DNS Client service:
# PowerShell (admin)
Restart-Service -Name Dnscache
Note: On some Windows versions, the DNS Client service is protected and can't be restarted directly. In that case, restart the network adapter instead:
# PowerShell (admin) — restart the network adapter
Restart-NetAdapter -Name "Wi-Fi"
# or
Restart-NetAdapter -Name "Ethernet"
You can list your adapter names with:
Get-NetAdapter
Linux — restart systemd-resolved:
sudo systemctl restart systemd-resolved
Check its status afterward:
systemctl status systemd-resolved
If you're using NetworkManager:
sudo systemctl restart NetworkManager
Linux — restart the network interface:
# Using ip (works on all modern distros)
sudo ip link set eth0 down && sudo ip link set eth0 up
# Using nmcli (NetworkManager)
sudo nmcli device disconnect eth0 && sudo nmcli device connect eth0
Replace eth0 with your actual interface name (ip link show to list them).
After restarting, re-run the tests from Steps 1–3 to see if the issue is resolved.
If public resolvers aren't answering (Step 3 failed even for 8.8.8.8), something between your machine and the resolver is blocking DNS traffic.
Check if a VPN is active:
# Linux — check for active VPN tunnel interfaces
ip link show | grep -E "tun|tap|wg"
# Or check for running VPN processes
ps aux | grep -E "openvpn|wireguard|vpn"
# Windows — check for VPN adapters
Get-NetAdapter | Where-Object { $_.InterfaceDescription -like "*VPN*" -or $_.InterfaceDescription -like "*TAP*" -or $_.InterfaceDescription -like "*TUN*" }
If a VPN is active, disconnect it and retest DNS. If DNS works without the VPN, the problem is in the VPN's DNS configuration.
Check firewall rules (Linux):
# Check for iptables rules that might block DNS (UDP/TCP port 53)
sudo iptables -L -n | grep -E "53|dns"
sudo iptables -L -n -t nat | grep -E "53|dns"
# For nftables
sudo nft list ruleset | grep -E "53|dns"
Check firewall rules (Windows):
# Check if outbound DNS is blocked
Get-NetFirewallRule | Where-Object { $_.Direction -eq 'Outbound' -and $_.Action -eq 'Block' } | Get-NetFirewallPortFilter | Where-Object { $_.LocalPort -eq '53' -or $_.RemotePort -eq '53' }
Check for DNS-over-HTTPS in the browser:
Modern browsers (Chrome, Firefox, Edge) can use DNS-over-HTTPS (DoH), which bypasses your system's DNS configuration entirely. This explains cases where the browser resolves fine but CLI tools don't — or vice versa.
chrome://settings/security → "Use secure DNS"about:preferences#privacy → "DNS over HTTPS"edge://settings/privacy → "Use secure DNS"If DoH is enabled in the browser, the browser uses its own DNS path, which can diverge from what nslookup and dig see.
If all devices on your network are failing DNS, the router is a prime suspect — especially if it's acting as a DNS proxy.
Check your default gateway:
# Linux
ip route show default
# Output: default via 192.168.1.1 dev eth0
# Windows
ipconfig /all
# Look for "Default Gateway"
Ping the gateway:
ping 192.168.1.1
If you can't ping your gateway, you have a LAN-level issue (cable, Wi-Fi, adapter) that needs fixing first.
Test DNS through the router vs. directly:
# Query through the router (if your router is 192.168.1.1)
nslookup google.com 192.168.1.1
# Query a public resolver directly
nslookup google.com 8.8.8.8
If the public resolver works but the router doesn't, the router's DNS proxy is the problem. Common fixes:
The cellular test:
The single fastest way to determine if the problem is your local network: disconnect a phone from Wi-Fi, use cellular data, and try to load a website. If cellular works and Wi-Fi doesn't, the problem is your local network or ISP, not the internet at large.
If most DNS resolution works but one domain (or a small set of domains) fails, the problem is likely with that domain's DNS configuration, not your resolver.
Query the specific domain against a public resolver:
nslookup failingdomain.com 8.8.8.8
dig @8.8.8.8 failingdomain.com
If this fails too, the domain's DNS may be misconfigured or its nameservers may be down.
Trace the full resolution path:
dig failingdomain.com +trace
This walks the resolution chain from the root servers down to the authoritative nameservers. You'll see exactly where the chain breaks. Look for:
Check the domain's nameservers directly:
# First, find the authoritative nameservers
dig NS failingdomain.com
# Then query one directly
dig @ns1.failingdomain.com failingdomain.com
If the authoritative nameservers don't respond, the problem is on the domain owner's side — there's nothing you can fix from the client end except wait (or contact the domain owner).
Check if it's a propagation issue:
If DNS records were recently changed, different resolvers may have different versions cached. This is where checking from multiple vantage points becomes essential. Run the same query against several public resolvers:
dig @8.8.8.8 failingdomain.com A
dig @1.1.1.1 failingdomain.com A
dig @9.9.9.9 failingdomain.com A
dig @208.67.222.222 failingdomain.com A # OpenDNS
If responses differ, propagation is still in progress. nslookup.io can give you a broader multi-resolver, multi-region view of propagation status — more on that in the next section.
A domain can also fail in ways that look like a generic timeout even when the authoritative servers are online. One common example is a DNSSEC validation failure: the zone responds, but signatures or DS records do not validate correctly at the recursive resolver. Some resolvers return SERVFAIL in this situation, while end users simply see that the name does not resolve.
Useful checks:
# See whether the resolver returns SERVFAIL
dig failingdomain.com A
# Query with DNSSEC details
dig failingdomain.com A +dnssec
# Compare a validating resolver and a non-validating or differently configured resolver
dig @1.1.1.1 failingdomain.com A +dnssec
If DNSSEC is involved, inspect the zone's DS, DNSKEY, and RRSIG chain carefully. A recent key rollover, missing DS update, or broken signing pipeline can create a failure that looks like a resolver outage from the client side.
If your configured resolver and public resolvers are all failing for the same query, the problem is likely upstream — at the authoritative nameserver level, or in the backbone routing to those nameservers.
Test multiple public resolvers:
for resolver in 8.8.8.8 1.1.1.1 9.9.9.9 208.67.222.222; do
echo "--- $resolver ---"
dig @$resolver failingdomain.com A +short +time=5
done
# Windows (PowerShell)
foreach ($resolver in @("8.8.8.8", "1.1.1.1", "9.9.9.9", "208.67.222.222")) {
Write-Host "--- $resolver ---"
nslookup failingdomain.com $resolver
}
Check response times and consistency:
dig @8.8.8.8 failingdomain.com | grep "Query time"
If query times are very high (>1000ms) or wildly inconsistent, the resolver or the path to the authoritative server is under stress.
Check if the resolver itself is healthy:
Public resolver operators often have status pages:
If a public resolver is having an outage, it'll usually show on these pages.
CLI tools like nslookup and dig are essential, but they show you DNS from one vantage point: your machine, using one resolver at a time. When you need a broader view — especially when troubleshooting propagation issues, inconsistent responses, or problems that only affect certain resolvers or regions — a web-based tool that queries from multiple resolvers simultaneously saves significant time.
The nslookup.io dashboard lets you enter a domain and record type and immediately see the response from multiple DNS resolvers. This is the equivalent of running dig against a dozen resolvers at once, but with the results organized side-by-side for easy comparison.
When you're at Step 8 in the troubleshooting workflow — suspecting a domain-specific issue — this is where the dashboard earns its keep. Instead of manually querying Google, Cloudflare, Quad9, and OpenDNS one at a time from your terminal, you can see all responses in a single view.
One of the most useful things you can do during DNS troubleshooting is compare what different resolvers return for the same query. If Google DNS returns one IP, Cloudflare returns another, and your ISP's resolver returns NXDOMAIN, you've immediately identified an inconsistency that narrows the problem.
On the nslookup.io dashboard, this comparison is the default behavior. You don't have to run separate queries — the multi-resolver results appear together. Look for:
DNS issues aren't always about A records. If email is broken, you need to check MX records. If TLS certificate validation is failing, CNAME or CAA records might be involved. If you've set up a new service and it's not resolving, maybe the AAAA record is fine but the A record is missing — or vice versa.
The dashboard lets you query any record type: A, AAAA, CNAME, MX, TXT, NS, SOA, and more. When troubleshooting, check the record type that's relevant to the service that's failing.
After making a DNS change, you want to know when the new record has propagated to major resolvers worldwide. Running dig from your local machine only tells you what one resolver thinks. The nslookup.io dashboard shows you how the change looks from multiple resolvers, giving you a clearer picture of propagation status.
A practical workflow: after updating a DNS record, check nslookup.io every 15–30 minutes until all queried resolvers return the new value. Once they do, you can be reasonably confident that most users will see the new record.
When your local tools give confusing or contradictory results, querying from an external tool provides an independent data point. If nslookup.io shows the correct record from all resolvers but your machine doesn't see it, the problem is definitively local — your cache, your resolver configuration, or something in your network path. This eliminates a huge category of possible causes in one step.
Manual troubleshooting is fine for one-off incidents, but if you're managing DNS for production infrastructure, you need programmatic access. The nslookup.io API lets you run DNS queries from code — useful for automated monitoring, post-change validation, and integration with your existing ops tooling.
nslookup.io publishes public API documentation for DNS lookups and related checks. For production use, treat the current API docs as the source of truth for endpoint paths, authentication requirements, quotas, and response schemas. In practice, the API is most useful for automated validation, propagation checks, and embedding DNS diagnostics into your existing monitoring or deployment workflows.
Use the request shape and authentication model shown in the current API documentation. A practical pattern is to send a domain name plus the record type you want to inspect, then parse the JSON response for returned values, TTLs, and any status or resolver metadata.
# Illustrative example — adapt the URL, headers, and parameters
# to the current nslookup.io API documentation before using in production.
curl -s "<nslookup.io-api-endpoint>" \
-H "Accept: application/json"
Python example — query a domain and check the result:
import requests
def check_dns(domain, record_type="A"):
"""Query the nslookup.io API for DNS records.
Replace the placeholder endpoint and any required authentication
with the values from the current API documentation before production use.
"""
url = f"<nslookup.io-api-endpoint-for>/{domain}/{record_type}"
headers = {"Accept": "application/json"}
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status()
data = response.json()
return data
# Example usage
result = check_dns("example.com", "A")
print(result)
When you need to compare how different resolvers answer the same query — the API equivalent of running dig @8.8.8.8, dig @1.1.1.1, etc. — you can make multiple API calls and compare the results:
import requests
def compare_resolvers(domain, record_type="A"):
"""Compare DNS results across resolvers via nslookup.io API."""
url = f"https://api.nslookup.io/dns-records/{domain}/{record_type}"
headers = {"Accept": "application/json"}
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status()
data = response.json()
# Parse and compare results from different resolvers
# The API response structure includes results from multiple resolvers
return data
result = compare_resolvers("example.com")
print(result)
This is a common use case: you've updated a DNS record and you want to programmatically check whether the new value has propagated.
import requests
import time
def wait_for_propagation(domain, record_type, expected_value, timeout=3600, interval=60):
"""Poll DNS until expected value appears or timeout is reached."""
start = time.time()
while time.time() - start < timeout:
url = f"https://api.nslookup.io/dns-records/{domain}/{record_type}"
headers = {"Accept": "application/json"}
try:
response = requests.get(url, headers=headers, timeout=10)
data = response.json()
# Check if expected value appears in the response records
# Adjust parsing based on actual API response structure
records = data.get("records", [])
values = [r.get("value") for r in records]
if expected_value in values:
elapsed = int(time.time() - start)
print(f"Propagation confirmed after {elapsed}s")
return True
else:
print(f"Not yet propagated. Current values: {values}")
except Exception as e:
print(f"Query failed: {e}")
time.sleep(interval)
print(f"Timeout after {timeout}s — propagation not confirmed")
return False
# Usage: wait for a new A record to appear
wait_for_propagation("app.example.com", "A", "203.0.113.50")
When integrating the API into monitoring or alerting systems, you'll want to parse the response into a structure your system understands. Key fields to extract:
Build your parsing based on the actual API response schema — refer to the nslookup.io API documentation for the current response format.
Model Context Protocol (MCP) is an open standard that lets AI assistants and automation tools connect to external data sources and services through a unified interface. Think of it as a way for tools to talk to each other without custom integration code for every combination. For DNS operations, MCP means you can connect DNS lookup capabilities directly into your automation workflows, chatops tools, and incident response runbooks without writing bespoke API glue code for each integration.
nslookup.io publicly documents an MCP server for AI and automation clients. If MCP fits your workflow, you can use it to expose DNS lookups, propagation checks, and related diagnostics inside supported clients without building a one-off integration for every tool in your stack.
Instead of writing a script that calls the REST API, parses the JSON, formats the output, and passes it to the next step, you define a workflow where DNS lookups are a native step. The MCP server handles the query, and the result flows directly into whatever comes next — whether that's a Slack notification, a PagerDuty incident update, or a deployment gate.
A common headache in CD pipelines is deploying a service behind a new hostname and then waiting (and hoping) for DNS to propagate. With MCP, you can build this into the pipeline:
Deployment pipeline:
1. Deploy the new service
2. Update the DNS record (via your DNS provider's API)
3. [MCP step] Query nslookup.io for the new record across multiple resolvers
4. If the new IP appears from all resolvers → mark deployment as complete
5. If not → wait 60s and retry (up to N times)
6. If propagation times out → alert the on-call engineer and pause the rollout
This removes the manual "check DNS, wait, check again" loop from your deployment process.
When an alert fires for "service unreachable," the first question is often "is this a DNS problem?" An MCP-based incident triage runbook can answer that automatically:
Incident triage workflow:
1. Alert fires: "api.example.com is returning 5xx errors"
2. [MCP step] Query nslookup.io for api.example.com A record
3. Compare result to expected IP from configuration
4. [MCP step] Query api.example.com from multiple resolvers
5. Check for inconsistencies or NXDOMAIN responses
6. Attach DNS diagnostic results to the incident ticket
7. If DNS is the root cause → route to the DNS/infrastructure team
8. If DNS looks fine → route to the application team
This shaves minutes off incident triage by eliminating the "let me SSH into a box and run dig" step.
MCP's value multiplies when it connects DNS checks to your existing observability stack. Platforms like Datadog, PagerDuty, Grafana, and Splunk can trigger or consume MCP workflows, meaning DNS validation becomes part of your overall monitoring fabric rather than a separate silo.
For example, a Datadog monitor that detects increased latency to a service could trigger an MCP workflow that checks whether the service's DNS records are resolving correctly and to the expected IP. The results get logged back to Datadog as custom metrics or events, giving you DNS observability alongside your existing application and infrastructure metrics.
Here are concrete scenarios where automating DNS checks prevents or shortens incidents.
Poll your critical domains at regular intervals and alert when something changes or breaks.
import requests
import time
CRITICAL_DOMAINS = [
{"domain": "api.example.com", "type": "A", "expected": "203.0.113.10"},
{"domain": "example.com", "type": "MX", "expected": "mail.example.com"},
{"domain": "app.example.com", "type": "CNAME", "expected": "lb.example.com"},
]
def check_domain(domain, record_type, expected_value):
"""Check a single domain against expected DNS value."""
try:
url = f"https://api.nslookup.io/dns-records/{domain}/{record_type}"
response = requests.get(url, headers={"Accept": "application/json"}, timeout=10)
data = response.json()
# Parse records from response (adjust based on actual API structure)
records = data.get("records", [])
values = [r.get("value") for r in records]
if expected_value not in values:
return {
"status": "MISMATCH",
"domain": domain,
"expected": expected_value,
"actual": values
}
return {"status": "OK", "domain": domain}
except Exception as e:
return {"status": "ERROR", "domain": domain, "error": str(e)}
def run_health_checks():
"""Run all DNS health checks and report failures."""
results = []
for check in CRITICAL_DOMAINS:
result = check_domain(check["domain"], check["type"], check["expected"])
results.append(result)
if result["status"] != "OK":
# Send alert — integrate with your alerting system
print(f"ALERT: {result}")
return results
# Run every 5 minutes (in practice, use cron or a scheduler)
while True:
run_health_checks()
time.sleep(300)
After updating DNS records, automatically verify that the change has propagated.
#!/bin/bash
# post-change-dns-check.sh
# Run after a DNS record update to verify propagation
DOMAIN="app.example.com"
RECORD_TYPE="A"
EXPECTED_IP="203.0.113.50"
MAX_ATTEMPTS=30
SLEEP_INTERVAL=60
echo "Waiting for $DOMAIN $RECORD_TYPE to resolve to $EXPECTED_IP..."
for attempt in $(seq 1 $MAX_ATTEMPTS); do
RESULT=$(dig +short @8.8.8.8 "$DOMAIN" "$RECORD_TYPE")
if [ "$RESULT" = "$EXPECTED_IP" ]; then
echo "SUCCESS: $DOMAIN resolves to $EXPECTED_IP after $attempt attempts"
exit 0
fi
echo "Attempt $attempt/$MAX_ATTEMPTS: got '$RESULT', expected '$EXPECTED_IP'"
sleep $SLEEP_INTERVAL
done
echo "FAILED: $DOMAIN did not resolve to $EXPECTED_IP within $((MAX_ATTEMPTS * SLEEP_INTERVAL / 60)) minutes"
exit 1
Detect split-brain DNS or inconsistent responses that could cause user-facing issues.
import subprocess
import json
RESOLVERS = {
"Google": "8.8.8.8",
"Cloudflare": "1.1.1.1",
"Quad9": "9.9.9.9",
"OpenDNS": "208.67.222.222",
}
def compare_resolvers(domain, record_type="A"):
"""Query a domain across multiple resolvers and compare results."""
results = {}
for name, ip in RESOLVERS.items():
try:
output = subprocess.run(
["dig", f"@{ip}", domain, record_type, "+short", "+time=5"],
capture_output=True, text=True, timeout=10
)
results[name] = output.stdout.strip().split("\n")
except Exception as e:
results[name] = [f"ERROR: {e}"]
# Check for inconsistencies
all_values = list(results.values())
consistent = all(v == all_values[0] for v in all_values)
return {
"domain": domain,
"consistent": consistent,
"results": results
}
# Usage
report = compare_resolvers("example.com")
if not report["consistent"]:
print(f"WARNING: Inconsistent DNS for {report['domain']}")
for resolver, values in report["results"].items():
print(f" {resolver}: {values}")
Track when cached records expire so you know when changes will take effect.
# Check the TTL remaining on a cached record
dig @8.8.8.8 example.com A | grep -E "^example" | awk '{print $2}'
# Output: 299 (seconds remaining)
import subprocess
import re
def get_ttl(domain, resolver="8.8.8.8", record_type="A"):
"""Get the remaining TTL for a domain's record from a specific resolver."""
output = subprocess.run(
["dig", f"@{resolver}", domain, record_type],
capture_output=True, text=True, timeout=10
)
# Parse TTL from the ANSWER section
for line in output.stdout.split("\n"):
if line.startswith(domain) or line.startswith(domain.rstrip(".") + "."):
parts = line.split()
if len(parts) >= 2:
return int(parts[1]) # TTL is the second field
return None
ttl = get_ttl("example.com")
if ttl is not None:
print(f"TTL remaining: {ttl} seconds ({ttl // 60} minutes)")
When an alert fires, automatically gather DNS data and attach it to the incident.
import requests
import json
from datetime import datetime
def enrich_incident_with_dns(domain, incident_id):
"""Gather DNS diagnostic data and attach to an incident ticket."""
enrichment = {
"timestamp": datetime.utcnow().isoformat(),
"domain": domain,
"checks": {}
}
# Check A record
try:
url = f"https://api.nslookup.io/dns-records/{domain}/A"
resp = requests.get(url, headers={"Accept": "application/json"}, timeout=10)
enrichment["checks"]["A_record"] = resp.json()
except Exception as e:
enrichment["checks"]["A_record"] = {"error": str(e)}
# Check NS records (are authoritative servers healthy?)
try:
url = f"https://api.nslookup.io/dns-records/{domain}/NS"
resp = requests.get(url, headers={"Accept": "application/json"}, timeout=10)
enrichment["checks"]["NS_records"] = resp.json()
except Exception as e:
enrichment["checks"]["NS_records"] = {"error": str(e)}
# Attach to incident (example — replace with your incident management API)
# pagerduty.add_note(incident_id, json.dumps(enrichment, indent=2))
# or
# slack.post_message(channel, f"DNS enrichment for {domain}:\n```{json.dumps(enrichment, indent=2)}```")
print(json.dumps(enrichment, indent=2))
return enrichment
# Usage — called automatically when an alert fires
enrich_incident_with_dns("api.example.com", "INC-12345")
You've identified the problem and applied a fix. Before you close the ticket or walk away, make sure it's actually resolved — and not just temporarily working.
Whatever command first showed the error, run it again:
# If this is what failed originally
nslookup google.com
# Or
dig failingdomain.com
A single successful response is encouraging but not conclusive. DNS issues can be intermittent, so a one-off success doesn't guarantee the problem is gone.
Run the query several times over a few minutes to check for consistency:
# Linux — run 10 queries with a 5-second interval
for i in $(seq 1 10); do
echo "--- Query $i ---"
dig +short example.com A
sleep 5
done
# Windows — run 10 queries
1..10 | ForEach-Object {
Write-Host "--- Query $_ ---"
nslookup example.com
Start-Sleep -Seconds 5
}
If all queries return the expected result consistently, you're in good shape.
Your local machine resolving correctly doesn't mean everyone else can. Check from external vantage points:
dig from thereDNS resolution is a means to an end. Check that the services that were affected are actually working again:
Don't just verify that DNS returns the right answer — verify that the thing DNS was blocking is now functional.
Set a reminder to check again in 30–60 minutes. Some DNS issues are intermittent or time-dependent (e.g., a resolver that fails under load during peak hours). If the problem recurs, you likely fixed the symptom but not the root cause.
If you have monitoring in place (or if you set up one of the automated checks from the previous section), configure it to alert you if the failure pattern reappears within the next 24 hours.
If you're checking results right after a fix and they still look wrong, flush your local cache before concluding the fix didn't work:
# Windows
ipconfig /flushdns
# Linux
resolvectl flush-caches
# macOS
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
Then retest. Stale cache entries are a common reason why a fix appears to not work immediately.
It means your computer sent a DNS query to its configured resolver and didn't get a response within the timeout period. The resolver is either unreachable (network issue, wrong IP, firewall blocking port 53), overloaded, or down. Your computer can't translate hostnames to IP addresses, so any service accessed by hostname will fail.
Start by flushing your DNS cache with ipconfig /flushdns, then test with nslookup google.com 8.8.8.8. If the public resolver works, your configured DNS server is the problem — try switching to Google DNS (8.8.8.8) or Cloudflare (1.1.1.1) in your adapter settings. If that doesn't work, restart your network adapter with Restart-NetAdapter in an elevated PowerShell prompt.
Intermittent DNS failures usually point to an overloaded resolver, packet loss on the network path to the resolver, or a resolver that's flaky under load. Run repeated queries (nslookup 10 times in a row) and note how many fail. Also try ping to the resolver's IP to check for packet loss. If your ISP's resolver is the problem, switching to a public resolver often improves reliability.
Both are reliable public DNS resolvers. Google DNS (8.8.8.8) has a longer track record and is widely used. Cloudflare DNS (1.1.1.1) generally offers slightly faster response times and has a stronger privacy commitment (they purge query logs within 24 hours). For most users, either is a good choice. You can configure both as primary and fallback: 1.1.1.1 as primary, 8.8.8.8 as secondary — or vice versa.
On Windows, run ipconfig /all and look for the "DNS Servers" line under your active adapter, or use Get-DnsClientServerAddress in PowerShell. On Linux, run resolvectl status (for systems using systemd-resolved) or cat /etc/resolv.conf. Note that on Linux, /etc/resolv.conf might point to 127.0.0.53 if systemd-resolved is active — the actual upstream servers are managed by systemd-resolved, not the file.
Yes, and it's one of the most common causes. Most VPN clients override your DNS settings when connected, routing queries through a DNS server on the VPN side. If that server is slow, unreachable, or doesn't resolve public domains, your DNS breaks. Split-tunnel VPN configurations can cause partial failures where some domains resolve and others don't. Disconnecting the VPN is the fastest way to test whether it's the cause.
It depends on the TTL (Time To Live) set on the old record. If the previous record had a 1-hour TTL, most resolvers will pick up the new record within 1 hour. If it was set to 24 hours, it can take up to 24 hours — or occasionally longer, since some resolvers don't strictly honor TTLs. Best practice is to lower the TTL well in advance (24–48 hours before the change) so the old record expires from caches faster.
Both query DNS servers, but dig provides more detailed output by default — including TTL values, query time, the full answer section, and authority and additional sections. dig also supports features like +trace (to walk the resolution chain from root to authoritative) and flexible output formatting. nslookup is simpler, available on Windows by default (while dig traditionally isn't), and sufficient for basic checks. On Linux, dig is the preferred tool for detailed troubleshooting.
Start with resolvectl status to check your current DNS configuration. Flush the cache with resolvectl flush-caches. If your resolver is wrong, check /etc/resolv.conf and determine whether it's managed by systemd-resolved, NetworkManager, or manually. Test against a public resolver with dig @8.8.8.8 example.com. If that works, update your resolver configuration. If systemd-resolved is the problem, restart it with sudo systemctl restart systemd-resolved.
Contact your ISP if their DNS resolvers are consistently failing (you've confirmed this by testing against public resolvers, which work fine), if the issue affects all devices on your network and persists after rebooting the router, or if you're seeing DNS-related issues that are specific to your ISP's infrastructure (like DNS hijacking or NXDOMAIN redirection to ad pages). Have your diagnostic results ready — including which resolvers work and which don't — so the support call is productive.
DNS problems are inevitable at some point, but the frequency and severity of those problems depend heavily on how you've set up and monitor your DNS infrastructure. Here are practices that make a measurable difference.
Configure redundant resolvers. Never rely on a single DNS server. Configure at least two resolvers — a primary and a fallback. If one goes down, your system automatically fails over to the other. On most operating systems, you can configure multiple DNS servers in your adapter or resolver settings.
Monitor DNS as part of your infrastructure observability. DNS is a critical dependency for almost everything, yet it's often the last thing teams think to monitor. Set up automated checks that query your critical domains at regular intervals and alert on failures, unexpected record changes, or resolution latency spikes. The nslookup.io API makes this straightforward to implement.
Automate post-change validation. Every time you update a DNS record, run automated checks to confirm the change has propagated. Don't rely on manual verification or hope — build it into your change workflow. The propagation polling script earlier in this article is a starting point; integrate it into your CI/CD pipeline or change management process.
Lower TTLs before planned changes. If you know you're going to change a DNS record, lower the TTL 24–48 hours in advance. This ensures that when you make the change, the old record expires from caches quickly. After the change has propagated and been verified, you can raise the TTL back to its normal value to reduce query load on the authoritative servers.
Document your DNS architecture. When an incident happens at 2am, the last thing you want to do is reverse-engineer which nameserver is authoritative for which zone, what resolver your production servers use, and where the DHCP configuration lives. Document it. Keep a runbook that covers the common DNS failure modes for your environment, the commands to diagnose them, and the steps to fix them.
Keep your local resolver stack healthy. If you're running local caching resolvers (like Unbound, dnsmasq, or systemd-resolved in caching mode), make sure they're configured correctly, restarted when the upstream configuration changes, and monitored for resource issues. A local resolver that silently runs out of file descriptors or cache memory can cause mysterious intermittent DNS failures.
Consider DNS-over-HTTPS or DNS-over-TLS for reliability. Beyond the privacy benefits, encrypted DNS protocols can improve reliability in networks where ISPs or middleboxes interfere with plain DNS traffic on port 53. If you're seeing unexplained DNS failures that go away when you use DoH or DoT, transparent DNS proxying or port-53 interference may be the cause.
Test from multiple perspectives. Your DNS working from your desk doesn't mean it works for your users in another region, on a different resolver, or through a different network path. Regular testing from multiple vantage points — using tools like nslookup.io for external checks and internal monitoring for your own infrastructure — catches problems that single-point testing misses.
DNS is one of those things that everybody takes for granted until it breaks. A small investment in monitoring, automation, and documentation pays for itself the first time you catch a propagation issue before your users notice, or the first time an on-call engineer resolves a DNS incident in minutes instead of hours because the runbook was there and the automated checks had already gathered the diagnostic data.