You set up WireGuard, the tunnel is up, traffic is flowing through the VPN, and then you run a DNS leak test — and your ISP's DNS server is right there, visible to every site you visit. That single misconfiguration defeats half the point of running a VPN. WireGuard is fast and modern, but unlike OpenVPN it does absolutely nothing to manage DNS on your behalf. If you do not explicitly tell the operating system which DNS server to use and lock it down, the OS will happily keep using whatever server it had before the tunnel came up. This guide explains exactly why leaks happen and gives you concrete, copy-paste fixes for Windows, Linux, and macOS.
What a DNS Leak Actually Is
When you type a domain name into a browser, the OS sends a DNS query before any TCP connection is made. If that query travels outside the encrypted WireGuard tunnel — even while all HTTP/HTTPS traffic goes through it — the DNS resolver your ISP assigned via DHCP sees every hostname you visit. Your real location and identity are exposed at the DNS layer even though your IP traffic is hidden.
WireGuard operates at Layer 3. It tunnels IP packets according to its AllowedIPs directive. DNS is just UDP port 53, and unless the DNS server's IP address is covered by AllowedIPs, those packets route around the tunnel entirely. That is the root cause of almost every WireGuard DNS leak.
The Three Most Common Causes
- DNS directive missing from the WireGuard config: The
[Interface]section has noDNS =line, so the OS keeps its existing resolver. - AllowedIPs does not cover the DNS server IP: You use a split-tunnel setup (e.g.,
AllowedIPs = 10.0.0.0/8) but your VPN DNS server is at, say,1.1.1.1, which is not in that range. - OS-level DNS leaks on Windows: Windows 8 and later use "Smart Multi-Homed Name Resolution" — it sends DNS queries to every adapter simultaneously and uses whichever responds first. WireGuard's DNS setting alone does not disable this.
Step 1: Set the DNS Directive in Your WireGuard Config
Open your WireGuard config file. On Linux this is typically /etc/wireguard/wg0.conf. On Windows and macOS it is managed through the WireGuard GUI app. Look at the [Interface] block and add or correct the DNS line:
In this example, 10.8.0.1 is the VPN server's internal IP address, which should be running a DNS resolver (Pi-hole, Unbound, or a simple forwarder). If your VPN provider gave you a specific DNS IP, use that instead. You can also use a public resolver like 1.1.1.1 or 9.9.9.9, but note the tradeoff: those queries will be encrypted inside the WireGuard tunnel but will ultimately leave through the VPN server's IP.
Using AllowedIPs = 0.0.0.0/0, ::/0 routes all traffic (IPv4 and IPv6) through the tunnel. This is a full-tunnel configuration and is the simplest way to prevent DNS leaks. If you are on a split-tunnel setup, continue to Step 2.
Step 2: Fix Split-Tunnel DNS Leaks with Correct AllowedIPs
If you only want certain subnets through the VPN, you must make sure the DNS server's IP is explicitly included in AllowedIPs. Otherwise DNS packets skip the tunnel.
This routes the VPN subnet, a private subnet, and both Cloudflare DNS server IPs through the tunnel. Adjust the IP addresses to match whatever DNS server you specified in the DNS = directive. If you are using 9.9.9.9 (Quad9), add 9.9.9.9/32 and 149.112.112.112/32 instead.
You can verify which routes are active after bringing up the interface with:
Step 3: Fix DNS Leaks on Windows
Windows is the most problematic platform for DNS leaks with WireGuard because of Smart Multi-Homed Name Resolution (SMHNR). Even with a correct DNS directive, Windows may still query the physical adapter's DNS server in parallel.
Option A: Disable Smart Multi-Homed Name Resolution via Group Policy
- Press Win + R, type
gpedit.msc, press Enter. - Navigate to Computer Configuration > Administrative Templates > Network > DNS Client.
- Double-click Turn off smart multi-homed name resolution.
- Set it to Enabled and click OK.
- Restart the WireGuard tunnel (deactivate and reactivate in the WireGuard app).
Option B: Disable SMHNR via Registry (Home editions)
If you are on Windows Home and do not have Group Policy Editor, use the registry instead:
Run those two commands in an elevated Command Prompt (right-click, Run as administrator), then reboot.
Option C: Set DNS per-adapter via PowerShell
After the WireGuard tunnel is active, force the physical adapter to use no DNS or a non-functional address so it cannot respond to DNS queries:
Step 4: Fix DNS Leaks on Linux with systemd-resolved
Most modern Linux distributions use systemd-resolved. WireGuard's DNS = directive sets the resolver for the interface, but without telling resolved to use it exclusively, other interfaces may still handle queries.
The Domains=~. line is critical — it tells systemd-resolved to use this DNS server for all domains (the tilde dot is a catch-all). Set FallbackDNS to empty so there is no fallback that could leak. Apply the changes:
Confirm the WireGuard interface shows the correct DNS server in the output of resolvectl status. If you are using wg-quick, it handles the resolvectl call automatically when you have a DNS = line, but the Domains=~. trick via PostUp ensures exclusivity:
Step 5: Fix IPv6 DNS Leaks
Many people fix IPv4 DNS leaks and forget about IPv6. If your machine has a global IPv6 address and your VPN does not route IPv6, DNS queries may go out over IPv6 to your ISP's IPv6 DNS server. The cleanest fix if your VPN does not support IPv6 is to include the IPv6 blackhole routes in AllowedIPs:
This drops all IPv6 traffic into the tunnel. If the VPN server does not have IPv6 configured, IPv6 connections will simply fail, which is acceptable for privacy — it is better than leaking. Alternatively, disable IPv6 on the physical adapter entirely:
Step 6: Add a Kill Switch to Prevent Leaks on Reconnect
Even with correct DNS configuration, a brief moment between tunnel drop and reconnect can expose DNS. A kill switch blocks all traffic outside the tunnel. On Linux with wg-quick, add these lines to your config:
This iptables rule blocks any packet that is not marked by WireGuard and is not destined for a local address. As soon as the tunnel drops, all outbound traffic is rejected until it comes back up.
How to Verify the Fix
Do not rely on a single test. Run all three of these checks:
Command-Line Verification
Windows Command-Line Verification
In the output of ipconfig /all, only the WireGuard adapter should show your intended DNS server. Every other adapter should either show no DNS server or an unusable address.
Web-Based Test
Navigate to a DNS leak test site while the WireGuard tunnel is active. You should see only the IP addresses of the DNS server you specified in your config. If you see any address belonging to your ISP, one of the steps above was not applied correctly. Use our DNS Lookup tool to cross-check which resolver is answering queries for a domain you just looked up inside the tunnel.
How to Prevent DNS Leaks Long-Term
- Always use full-tunnel routing (
0.0.0.0/0, ::/0) unless you have a specific operational reason for split-tunnel. Full tunnel is the default-safe option. - Use DNS over the tunnel only: Set
DNS =to an IP that is inside your VPN subnet or is explicitly routed through AllowedIPs. - Run your own resolver on the VPN server: A local Unbound or Pi-hole instance means DNS never leaves the server you control.
- Automate the kill switch: Use the PostUp/PreDown iptables approach shown above so the protection is always active when the tunnel is, and never needs to be remembered manually.
- Test after every config change: Any time you update the WireGuard config, run
resolvectl statusand a web leak test before considering the job done. - Keep WireGuard updated: Run
sudo apt upgrade wireguard(Debian/Ubuntu) or the equivalent for your distro regularly. Bugs in the DNS handling ofwg-quickhave been fixed in past releases.
Quick Reference: Minimal Leak-Free WireGuard Config
If you want a clean template that incorporates all the fixes above for a full-tunnel Linux client, here it is:
This configuration routes all IPv4 and IPv6 traffic through the tunnel, sets DNS to the VPN server's internal address, locks systemd-resolved to use only that server, and enforces an iptables kill switch. It is the baseline every WireGuard deployment should start from when privacy and leak prevention are the goal.