What Is FakeDNS: How the Xray Core Resolves Domains with Virtual IPs and When to Enable It

FakeDNS temporarily answers with a virtual IP from the reserved 198.18.0.0/15 range, letting apps connect immediately and deferring real DNS resolution to the outbound stage. This article covers where it intercepts, how to configure it, how to enable it in clients, and four scenarios where you should leave it off.

In this article

This article explains how FakeDNS substitutes virtual IPs for real DNS answers and how to configure it. It's written for users setting up TUN transparent proxy who want domain-based routing rules to keep working, and it helps you decide whether to enable it and how to verify it afterwards.

The full path of a request: where FakeDNS steps in

App sends a requestDNS query is interceptedA virtual IP is returnedApp connects to the virtual IPDomain is looked up to match rulesTraffic goes out through the proxy and is resolved

Without FakeDNS, an app first asks the system DNS server for the domain's real IP and then connects to that address. Under TUN mode the core sees IP packets, so if the destination doesn't match any rule, the domain information is lost and routing has to fall back to IP-based rules.

With FakeDNS enabled, DNS queries are handled by the Xray DNS module. Instead of asking the upstream DNS server for a real address, it picks an unused IP from the 198.18.0.0/15 range and records a domain-to-virtual-IP mapping in memory.

The app then connects to that virtual IP. When the traffic enters the TUN interface, the routing engine sees that the destination falls inside the FakeDNS range, looks up the original domain through the mapping table, and geosite, domain, and other rules match as usual before the traffic is handed to the right outbound.

Real DNS resolution is deferred to the outbound stage and performed by the proxy server on the remote end. For proxied traffic, that saves one local DNS round trip and makes connection establishment faster.

The point of FakeDNS is not to forward DNS queries through the proxy, but to skip local resolution entirely and resolve only at the outbound stage. The round trip you save comes from the virtual IP letting the app connect immediately.

The virtual IP pool: where 198.18.0.0/15 comes from and why it won't conflict

198.18.0.0/15
Default virtual IP pool
131072
Available addresses in the pool
1
Local DNS round trips saved

198.18.0.0/15 covers 198.18.0.0 through 198.19.255.255, for a total of 131,072 addresses. This range is reserved by RFC 2544 for network device performance testing, and no public service is deployed there, so using it for virtual addresses won't conflict with any real site.

The mapping table stays in memory and entries are reclaimed as soon as a connection ends, so the default pool is more than enough for everyday use. Xray also lets you change the range through the root-level fakedns pool field, but the default is fine in most cases.

Configuration: fake server entries and the root-level fakedns field

{
  "dns": {
    "servers": [
      "https://1.1.1.1/dns-query",
      {
        "address": "fake",
        "domains": ["geosite:geolocation-!cn"]
      }
    ]
  }
}

The first entry is a regular DoH server that handles real resolution; the second entry with address set to fake hands out virtual IPs. The domains filter decides which domains go through fake — in the example above, only non-China domains get virtual IPs, while domestic domains are still resolved normally by 1.1.1.1.

If you'd rather not edit the servers array by hand, Xray 1.8.0 and later support a root-level fakedns field that is equivalent to injecting a fake server entry automatically. It's a good fit if you just want a switch without touching the config:

{
  "fakedns": {
    "pool": "198.18.0.0/15",
    "skipFallback": false
  }
}

skipFallback controls fallback behavior: when set to false, domains not handled by the fake entry keep looking for other DNS servers in the list; when set to true, it returns a failure immediately. Leave it at the default false for everyday use.

Enabling FakeDNS in v2rayN and v2rayNG

v2rayN desktop

Menu location
Settings → Parameter Settings
Section
Routing
Toggle
Enable FakeDNS
Core requirement
Xray core
How to apply
Restart the core

Keep the domain resolution strategy set to AsIs; do not switch to IPOnDemand.

v2rayNG on Android

Menu location
Settings → DNS Settings
Toggle
Enable FakeDNS
Core requirement
Xray core
How to apply
Restart the app after going back

The v2fly core also recognizes DNS entries with address set to fake, so v2flyNG users can enable it in a custom config.

In both clients, the toggle only affects the config generated for the core, so you must restart the core or the app for the DNS module to pick up the new state.

The first thing to do after enabling it is to visit a domestic site and confirm it goes direct and isn't taken over by fake. This catches mistakes in the domains filter early and is more effective than testing a foreign site right away.

Four scenarios where you should not enable FakeDNS

There's only one test: traffic must go through the TUN interface and routing must be primarily domain-based. If either condition is missing, FakeDNS offers little benefit while its side effects can break connections outright.

Before enabling it, write down your current domain resolution strategy and DNS server list. Most FakeDNS problems come from DNS configuration, and keeping a reference makes it easy to restore.

How to verify FakeDNS and common issues

The quickest way to check whether FakeDNS is active is to look at the core log. After enabling it, visit a foreign site and the log should show something like this:

2026/07/24 10:32:11 [Info] [TCP] dialing to target:198.18.0.7:443 via proxy

If the destination is 198.18.x.x, the connection really used a virtual IP; combined with the domain shown in the routing log, you can confirm that both FakeDNS and your domain rules are working.

Domestic direct sites got slower after enabling FakeDNS?

That means domestic domains are being taken over by fake too. Narrow the domains filter on the fake entry to a set of non-China domains (such as geosite:geolocation-!cn), keep domestic domains on a regular DNS server, then restart the core and test again.

Some apps can't connect at all under TUN mode?

These apps usually validate the destination IP or use custom UDP. Add a direct rule for that app or exclude it by process so its traffic doesn't go through TUN — there's no need to disable FakeDNS globally.

Everything works after turning FakeDNS off — what was wrong?

It's usually the DNS server order or a mistake in the domains filter. Restore the default DNS config first, then add entries back one at a time following the pattern of non-China domains through fake and domestic domains through local resolution, changing only one thing at a time.

Do I need FakeDNS in system proxy mode?

No. Under system proxy, the app already hands the domain to v2rayN and routing matches by domain directly. FakeDNS only pays off with TUN transparent proxy, so leave it off in system proxy mode.

v2rayN Download