Use this guide if websites load through the proxy but DNS leak tests still show your local ISP's resolvers, or if changing DNS settings makes some domains unreachable. First, distinguish the browser, operating system, and core DNS paths. Then compare test results to identify where requests originate, and merge the DNS and routing snippets for your current core. These examples are not complete node configs and must not replace your existing proxy outbound.
How to identify a DNS leak: check the resolver path, not just its location
A DNS leak occurs when domain lookups that should follow your intended proxy path are sent to an unexpected resolver instead. For example, a web connection may use the proxy while an app first queries the router, which then forwards the request to your local ISP. A changed public IP does not mean your DNS requests follow the same route.
Browser Secure DNS, operating system DNS, and V2Ray's built-in dns can all be active at the same time. A setting only applies when a request enters the corresponding processing path. A system proxy usually handles connections from apps that honor proxy settings; it does not capture every UDP query. Adding dns.servers to JSON does not automatically take over DNS for the network adapter.
- Browser resolves the domain: With Secure DNS enabled, the browser may query its configured DoH service directly instead of using the system resolver.
- System resolves the domain first: The app gets an IP address before handing the connection to the proxy. The core may receive only the IP and cannot undo a query that has already been sent.
- Core resolves on demand: IP-based routing matches, some outbound connections, or DNS inbound forwarding can trigger built-in resolution, but this does not guarantee coverage for other processes.
First, identify who operates the resolver
A different country shown on a DNS test page is not, by itself, proof of a leak. Record the resolver address and operator, then check whether it belongs to your intended DNS service. Anycast routing and the test site's geolocation database can both affect the location shown.
DNS leak test steps: compare direct and proxied connections
Keep the browser, network, and test service the same throughout. For each test, record the public IP, resolver IP, browser Secure DNS status, and client routing mode. The steps below explain how to test; they are not results from this site. Do not treat the number of resolvers in a single test as a universal pass/fail threshold.
Record a baseline
Temporarily disconnect the proxy and run a DNS leak test in your browser. Note the resolver addresses and operators. If you're on a shared workplace network or managed device, check whether you can change network settings first.
Keep the browser settings consistent
Search for “Secure DNS” in the browser's Settings and note its current status. To isolate browser-based resolution, you can temporarily turn it off while troubleshooting, then restore the original setting. Don't change system DNS at the same time.
Enable the proxy
Start v2rayN, then select “Auto configure system proxy” from the tray menu under “System Proxy.” Confirm the active server and routing mode. Reopen the test page and run a fresh test.
Clear the cache
In Windows Terminal, run
ipconfig /flushdns, then fully close and reopen the browser. This command clears only the system DNS cache; it does not clear the browser's own cache.Retest one setting at a time
Change just one variable per test: start with browser DNS, then core DNS, and finally the interception method. Run at least two rounds. If results vary, keep the timestamps and logs so an old cache isn't mistaken for a newly applied setting.
Command-line tests can help identify where a request enters the network stack. The example uses SOCKS port 10808; use the port configured in your client. --socks5-hostname sends the destination domain to the SOCKS proxy. It verifies how that app connection handles the domain, but cannot prove that DNS is not bypassing the proxy elsewhere on the system.
curl.exe --proxy socks5h://127.0.0.1:10808 https://example.com/ --head
ipconfig /flushdns
Resolve-DnsName example.com -Type A
Run the last command in PowerShell. It will usually use the system DNS path and won't be routed through V2Ray just because an HTTP system proxy is configured. If its result differs from the browser's, that shows they use different entry points; it does not, by itself, mean the core config is failing.
Ports and protocols: distinguish local proxy, DNS, and DoH
Don't set the network adapter's DNS to 127.0.0.1 unless a local DNS service is actually listening on the corresponding port. SOCKS and DNS listeners use different protocols: sending a query to 10808 won't produce a DNS response. Some clients use a mixed-protocol listener, so check the generated config for your current setup.
| Setting | What it does | What it does not guarantee |
|---|---|---|
| System network adapter DNS | Used by programs that follow the system's DNS settings | Does not ensure the browser's built-in DoH uses the same service |
Core dns.servers | Sets the upstream for built-in DNS queries | Does not automatically capture queries from other programs |
routing.rules | Determines which outbound handles connections that enter the core | Does not change resolutions completed outside the core |
| TUN DNS interception | Captures or redirects DNS traffic, depending on the implementation | Does not guarantee that all encrypted DNS traffic will be detected and rewritten |
Configuring dns.servers: route DNS queries through an explicit outbound
This V2Ray/Xray-style snippet shows how to configure remote DoH and tag DNS traffic. Your current core must support these fields, and your existing outbounds must include a usable proxy outbound named proxy. If your tag is different, replace it with the actual value. Do not start the core with this snippet as a complete config.
{
"dns": {
"tag": "dns-query",
"servers": [
"https://1.1.1.1/dns-query"
],
"queryStrategy": "UseIPv4"
},
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"inboundTag": ["dns-query"],
"outboundTag": "proxy"
}
]
}
}
dns.tag: Adds a routing tag to queries made by the built-in DNS. Here,inboundTagmatchesdns-query; this does not create a SOCKS inbound.servers: This example uses an IP-based DoH address to avoid a bootstrap lookup for the DNS service's hostname. You still need to verify that the service is reachable on your network and proxy route.queryStrategy:UseIPv4limits built-in DNS queries to IPv4, which helps rule out IPv6 path differences. Once the config is confirmed in a dual-stack environment, you can evaluateUseIP.- Rule order: Place this specific DNS rule before broad direct-connection rules, and keep your other existing rules. If an earlier rule already matches, a later DNS proxy rule cannot override it.
DoH encrypts the connection between the client and the DNS service; whether that connection uses the proxy depends on routing. Some cores support local handling modes with names ending in +local, which route traffic differently from standard remote modes. Don't swap one in here just to “make it faster.” For split DNS, add upstream rules scoped to specific domains and check whether fallback resolution could use an unexpected service.
domainStrategy: check routing resolution and outbound resolution separately
domainStrategy is not a global DNS leak prevention switch. The same key controls different stages depending on which object contains it. When troubleshooting, check the full JSON hierarchy; searching for the key and replacing every occurrence can cause problems.
| Field location or value | Behavior | What to check |
|---|---|---|
routing.domainStrategy: AsIs | Does not resolve domains for IP rules during routing | Check that domain rules and the default outbound are configured correctly |
routing.domainStrategy: IPIfNonMatch | If a domain doesn't match a rule, tries resolving it before matching IP rules | Check which DNS upstream handles the lookup |
routing.domainStrategy: IPOnDemand | Triggers resolution when a rule needs an IP address to make a decision | Check where IP rules appear and how many extra lookups they cause |
freedom.settings.domainStrategy | Controls how direct outbounds handle destination domains | Whether it uses the system resolver or built-in DNS depends on the value and core |
AsIs applies only during routing; it doesn't mean the destination is never resolved. A connection sent through a direct outbound still needs a destination address. If the domain is sent to the proxy as a hostname, the remote end usually handles resolution. If you keep direct access for sites in mainland China, define how their domains should be resolved instead of treating every local DNS request as a problem.
Set the DNS outbound first, then adjust matching behavior
First, verify that traffic tagged dns-query actually uses the proxy outbound. Then choose AsIs or another strategy to fit your split-routing setup. Changing IPIfNonMatch to AsIs alone cannot fix local resolution that happened before the app's request reached the core.
FakeDNS: address mapping does not intercept traffic
FakeDNS returns a mapped address from a reserved IP pool, not the real destination address. The core stores the mapping between the domain and that address. Later connections must return to the same processing path so the domain can be recovered from the mapping. FakeDNS is suited to setups with DNS interception and connection recovery; enabling a single config field is not enough.
{
"fakedns": [
{
"ipPool": "198.18.0.0/15",
"poolSize": 65535
}
],
"dns": {
"servers": ["fakedns"]
}
}
This conceptual snippet is for V2Ray/Xray cores that support FakeDNS. It does not include a DNS inbound, forwarding, or system routing. For an existing inbound that needs to restore mappings, merge the following sniffing settings as supported by your core. Don't create an empty inbound that real traffic will never reach.
{
"sniffing": {
"enabled": true,
"destOverride": ["fakedns"]
}
}
- DNS queries must reach the core: Setting only
"servers": ["fakedns"]in JSON does not make the Windows network adapter query it automatically. - Mapped connections must be intercepted:
198.18.0.0/15is not a public website address. If the system sends it straight to the physical gateway, the page will typically time out. - Routing must be consistent: Make sure the address pool does not conflict with your existing network and is handled by the active interception path. Don't add it to a direct-connection bypass list.
- Clear caches after switching: If you turn off FakeDNS or restart the core and lose its mappings, mapped addresses in the old cache may no longer work. Query the domains again to create fresh mappings and connections.
v2rayN can manage different cores, and TUN DNS interception may use a different config structure. Check which core is actually running before applying the V2Ray/Xray config above. Don't paste this JSON into a TUN DNS screen for another core.
v2rayN settings and common errors
In the desktop app, first check the local listening ports under “Settings” → “Parameter Settings.” Then open “Settings” → “DNS Settings” and review the DNS options for the active core. Some versions place DNS settings under Parameter Settings, and available fields vary by core. Save your changes, restart the service, and check the runtime log to confirm which core is running and whether it loaded the config. Recheck the generated config after updating the client, refreshing a subscription, or switching configs.
For system proxy troubleshooting, use “System Proxy” in the tray menu. For DNS interception, check “TUN Mode” and its settings in the main window; these are separate controls. TUN may require elevated permissions or conflict with an existing virtual adapter, so note the original settings before making changes. Don't run multiple traffic interception tools at once to compare results.
Error: failed to find an available destination
Possible cause: The node hostname may not resolve, or none of the candidate addresses may be reachable. This message alone does not prove a DNS leak. What to do: Check the surrounding log entries. First verify that the node address resolves, then check DNS outbound dependencies and node connectivity.
Error: lookup example.com: no such host
Possible cause: The current resolution path did not return a valid record for the domain; the actual hostname in the log may be different. What to do: Check the spelling, upstream response, and split-routing restrictions. Compare with another domain known to resolve; don't change the listening port as a first step.
Error: context deadline exceeded
Possible cause: An operation exceeded its timeout, which can happen during DNS resolution or a later connection. What to do: Use the destination address in the logs to identify which stage timed out. If the destination is a DoH service, check that it uses the expected outbound and that the proxy is reachable.
On Android, check which core is in use: v2rayNG uses Xray, while v2flyNG uses V2Fly. System VPN interception, app bypass lists, and Android Private DNS can all change the resolution path, so don't assume desktop system proxy findings apply. If the same node behaves differently on the two platforms, compare the entry point and resolver before blaming the node.
- How to confirm the fix: Repeated tests show only the expected resolvers for the app under test, and logs show DNS traffic using the expected outbound.
- How to confirm split routing: Test direct and proxied domains separately. Check both the DNS results and whether each site can establish a connection.
- System-wide verification: To cover more apps, also check UDP/TCP 53, encrypted DNS in browsers, and IPv6 paths. A test on one website cannot cover every process.
- How to roll back: Save the original config and change one layer at a time. If something goes wrong, restore that setting, restart the service, and clear the cache. Don't stack more changes on top of multiple misconfigured settings.