Advanced Config ~17 min read

Configure Clash Meta nameserver-policy: Per-Domain DoH Step by Step (2026)

One global DoH resolver sounds tidy until you need domestic CDNs to resolve like your ISP expects while work domains and overseas SaaS still prefer a privacy-forward path. In Clash Meta (Mihomo), nameserver-policy is the knob that sends each query class to the resolver list you intend—this guide shows how to write the map cleanly, how it interacts with FakeIP, and how to verify you are not fooling yourself with cached or out-of-band answers.

Clash Editorial Team Clash Meta · Mihomo · nameserver-policy · DoH · split DNS

Why a Single Resolver Stack Stops Being Enough

If you are here, you have probably already enabled encrypted DNS in the dns stanza and maybe even standardized everything on a single public DoH endpoint. That is a solid baseline for privacy against passive observation on port 53, but it is often the wrong abstraction when your rules implicitly assume geography. CDNs issue different A/AAAA answers depending on where the recursive resolver appears on the map, which means the same hostname can point to different edges for a resolver in Tokyo, Frankfurt, or a regional ISP anycast. When your traffic policy says “send domestic services DIRECT” but the resolver you picked returns an overseas POP optimized for privacy rather than locality, you get the classic failure mode: pages load yet video buffers, app stores crawl, or an enterprise SSO flow negotiates the wrong regional shard.

Another class of problems is regulatory or operational: some organizations want strictly domestic recursion for certain suffixes while still tunneling others through a proxy group. You cannot express that intent with a lone nameserver: list unless you are willing to fork entire profiles per device. The intended Mihomo mechanism is to add a policy layer on top of defaults so each queried name picks upstreams by pattern. That mechanism is nameserver-policy, and it pairs naturally with geosite: data sets or hand-maintained suffix lists. The mental model is simple even if YAML grows long: default resolvers handle the long tail; overrides steer sensitive buckets without forcing you to disable FakeIP globally or rip out DoH entirely.

This article stays deliberately narrow. For the full DNS leak story—why OS resolvers fight the core, how tun.dns-hijack closes bypasses, and when fake-ip-filter matters—read our Meta core DNS leak prevention guide and the companion piece on Clash Meta fake-ip-filter for LAN and direct domains. Here we zoom into policy authoring and the verification loop so you can prove, from logs, which upstream actually answered edge.example before you spend another evening toggling nodes at random.

What nameserver-policy Actually Controls

In Mihomo-compatible cores, DNS resolution is a pipeline: a client asks the local listener, the listener consults routing context, then it chooses a set of recursive servers to query. The nameserver-policy table is evaluated when forming that choice for a given QNAME. Keys are matchers—commonly geosite:cn for curated Chinese traffic categories, +.example.com for suffix coverage, or literal hostnames if you need surgical control. Values are lists of upstream entries that mirror what you would place under nameserver:, including https:// DoH URLs, tls:// DoT endpoints, plain IP literals for bootstrap-friendly paths, and #GroupName suffixes that pin the query transport to an existing proxy outbound.

Nothing in this table decides whether the eventual TCP connection goes DIRECT or through PROXY. Policy affects who answers the DNS question; your rules section still owns the data plane once an IP or domain is known. That separation is powerful because you can reuse a single outbound map across devices while shifting resolver footprints per region. It is also where people get hurt: a “perfect” resolver map paired with sloppy rule ordering still yields inconsistent behavior because the IP you got is valid yet wrong for the node you selected. Successful profiles treat resolver policy and routing policy as two sides of one design sheet, updating both whenever you introduce new domain bundles.

Prerequisites Before You Touch Policy Maps

Start from a known-good skeleton. dns.enable should be true, you should know whether you run enhanced-mode: fake-ip or a redir-host style configuration, and you need at least one bootstrap-safe path that can resolve the hostnames embedded inside your DoH URLs without circular dependence. In practice that means maintaining proxy-server-nameserver: entries that the core can hit to unlock TLS to your primary resolvers when those URLs are not raw IPs. If you skip that layer, you will troubleshoot policy forever while the real failure is simply failing to complete the first TLS handshake to the recursive.

Document your outbound groups before tagging resolvers. A pattern that works well for privacy-focused users is to suffix encrypted upstreams with #PROXY so recursion never falls back to an unintended DIRECT path when your threat model says the ISP must not see query metadata. Conversely, domestic resolvers sometimes need to ride DIRECT to match CDN steering accurately—be explicit rather than relying on implicit defaults that change when you reorder groups. If your subscription provider ships a gigantic template, resist the urge to paste mystery upstreams; verify each hostname resolves and each DoH URL matches the port and path the operator documents.

Ordering intuition: More specific domain keys should win over broad geosite buckets. If two keys could match, expect the more specific policy to take effect—when in doubt, log and test.

Step 1: Write a Deliberate Default nameserver List

Policy overrides inherit context from your defaults. If defaults are chaotic—mixed plaintext and encrypted, inconsistent proxy tags, or duplicated resolvers racing with different ECS behavior—you will see jitter that looks like policy bugs. Pick one primary stack for “everything else” after your overrides. Many profiles use a fast anycast DoH pair tagged through #PROXY plus a conservative fallback for rare failures. Keep the list short; long parallel races inflate complexity without guaranteeing better answers. When you later add nameserver-policy, think of it as trimming exceptions away from that baseline rather than inventing a second baseline hidden inside overrides.

If you operate both laptop and gateway builds, keep defaults parallel across them. Divergent defaults plus identical policy maps still produce different effective behavior because one device might resolve bootstrap names through a router dnsmasq forwarder while another uses system stub resolvers. Where possible, let Clash own the listener on 127.0.0.1 or document exactly which upstream the OS hands to when Clash is paused. That discipline pays off the first time you compare logs between two machines that supposedly run the same YAML.

Step 2: Declare DoH Upstreams You Trust per Region

For each region or trust domain, write at least one DoH endpoint you are willing to explain to your future self. Domestic profiles frequently include operator resolvers optimized for local CDN aliasing, while overseas bundles might emphasize logging policies or ECS handling that fits SaaS tools. Avoid copying fifty resolvers from forum screenshots; pick two or three with distinct routing and monitor their latency weekly. If you need redundant paths, prefer true multi-provider diversity rather than six aliases of the same anycast cloud.

When you reference a proxy group with #PROXY, make sure that group actually contains healthy nodes capable of reaching the resolver URL. A silent degradation pattern is pointing policy at https://dns.google/dns-query#PROXY while your PROXY group is empty after a failed subscription refresh. The DNS layer then stalls or falls back in ways GUI summaries undersell. Automate subscription health checks or at least surface empty groups prominently; DNS is often the first subsystem that screams when upstream lists rot.

Step 3: Author nameserver-policy with Realistic Keys

Begin with the broad buckets your rules already reference. If you maintain a geosite:cn direct policy for domestic traffic, mirror that intent in DNS by steering those names to resolvers that return answers consistent with on-shore routing. If you operate multinational SaaS split tunnels, carve per-suffix maps for the vendor’s auth, API, and edge domains rather than relying on a single apex rule. The YAML structure is readable once you accept it is just a mapping object:

dns:
  enable: true
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  nameserver:
    - https://1.1.1.1/dns-query#PROXY
    - tls://1.1.1.1#PROXY
  proxy-server-nameserver:
    - https://223.5.5.5/dns-query
  nameserver-policy:
    "geosite:cn":
      - https://dns.alidns.com/dns-query
      - https://doh.pub/dns-query
    "+.office.example":
      - https://internal-doh.corp.example/dns-query#CorpVPN
    "+.streaming-example.net":
      - https://dns.google/dns-query#PROXY

The snippet is illustrative: rename groups, drop enterprise internals you do not host, and never paste secrets. Notice how geosite:cn stays on presumably domestic HTTPS resolvers without forcing those queries through a foreign tunnel, while a fictional SaaS suffix might still prefer Google’s recursive but only after tagging the transport through #PROXY. Tailor the story to your geography—swap AliDNS and DoH Pub equivalents if your operator documents better paths for your province or AS.

Use literal host keys when geosite lists lag behind reality. Newly launched microservices often appear under oddly named fourth-level domains; until category files catch up, pinning +.cdn.vendor.com saves hours. Keep a changelog in your private git repo so you can drop stale suffixes after vendors migrate CDNs. Nothing undermines trust in your profile faster than hundreds of dead policy keys that nobody dares delete because they once fixed a mysterious outage.

Step 4: Align fake-ip-filter, Sniffer, and Routing Rules

FakeIP accelerates rule evaluation by synthesizing addresses for most hostnames, but hostnames you expect to resolve “for real” still belong in fake-ip-filter. When you add aggressive nameserver-policy splits, revisit that filter: LAN names, captive portal helpers, and certain gaming anti-cheat stacks often need predictable answers. If a hostname sits in policy but also should never receive synthetic addresses, ensure both layers agree. Misalignment shows up as suspicious partial connectivity—TLS succeeds yet application logic insists the region is wrong because it double-checked DNS outside the tunnel.

Routing rules should mention the same domain vocabulary your policy uses. If policy pins +.stream.example to an anycast resolver tuned for continent A but your browser traffic still matches a broad GEOIP bucket sending video through continent B, you will battle symptoms that look like DNS bugs. Consider promoting exact DOMAIN-SUFFIX rules ahead of catch-all geographic matchers when streaming reliability matters. Our scenario articles on split routing repeatedly emphasize that ordering discipline; the DNS guide here is not a substitute for rule hygiene.

Step 5: Close OS and Browser Bypasses with TUN

Writing YAML is half the battle; modern operating systems ship competing stub resolvers, VPN interfaces, and “secure DNS” toggles that happily skip your Clash listener. If queries never hit Mihomo, nameserver-policy is inert. On setups that need full capture, pair TUN mode with documented tun.dns-hijack patterns so stray UDP 53 and sometimes dot traffic are dragged back into the core pipeline. Validate after every OS upgrade—vendors love to reset user choices for “security improvements” that silently re-enable public DoH in the browser while leaving system resolver pointed at Clash only on paper.

Mobile tethering and corporate always-on VPNs are repeat offenders. When you hop from Ethernet to Wi-Fi to hotspot, resolver priority tables reorder themselves. A quick post-switch ritual—open logs, trigger a lookup, confirm Clash sees it—catches regressions before you blame the wrong node. Power users sometimes maintain checklist scripts that run dig against the loopback listener and compare answers to an expected pattern list; that sounds obsessive until it saves a demo day.

ECS and anycast traps: Different resolvers advertise different client subnet hints. If you chase millisecond wins, benchmark realistic domains, not only example.com.

Step 6: Verify With Logs, Not Vibes

Verification should answer a precise question: for hostname H at time T, which upstream list evaluated, which address set returned, and which outbound carried the subsequent TCP session? Start by reproducing H under controlled conditions—close redundant tabs, flush application caches if feasible, restart the Mihomo core to clear internal state when debugging stubborn cases. Enable the verbose logging your GUI exposes; phrases differ by client, but you are hunting lines that mention DNS resolution, upstream selection, and failed TLS to recursive endpoints.

Second, compare against an independent baseline. If policy claims domestic recursion for a suffix, query the same name through a trusted on-net resolver from a machine that does not run Clash and compare canonical names and TTLs—not just bare IPv4 equality. CDNs love CNAME chains; two answers may look numerically different yet both be “right” for different Steering policies. Third, roll forward carefully: change one policy stanza or one rule line between tests. Multi-knob edits make postmortems impossible even if you stumble onto a lucky combination.

  1. Identify a canary hostname per bucket (domestic media, work SSO, global SaaS) and record baseline answers.
  2. Apply policy, reload Mihomo, repeat lookups through the Clash listener only.
  3. Correlate observed IPs with traceroutes or simple HTTPS GETs through the intended outbound group.
  4. Toggle off secure DNS in browsers temporarily to eliminate split confusion during the test window.
  5. Document outcomes in your notes so the next profile refresh preserves lessons.

Common Foot-Guns and How to Dodge Them

Beginners often assume nameserver-policy magically fixes GEOIP miscoloring; experts know it only narrows resolver divergence. If you see mismatched flags, revisit both resolver and rule layers. Another frequent mistake is stuffing huge static domain lists into policy without deduplicating overlapping suffixes, which makes maintenance intimidating and error-prone. Prefer curated data sets where possible, supplement with literals only for gaps, and delete entries once vendors consolidate hostnames.

Also watch bootstrap circularity: policy entries that reference corporate DoH hostnames need a resolver path that can resolve those hostnames before TLS comes up. Split horizons sometimes require internal plain-DNS hops on trusted networks—document that dependency rather than pretending every environment is zero-trust clean. Finally, keep subscription converters and remote rule providers in mind: regenerating YAML from upstream templates can silently drop custom dns: sections unless you pin local overrides in client-specific merge files.

Summary

nameserver-policy is the surgical tool that keeps Clash Meta resolver choices aligned with your geopolitical and operational reality. Build defaults you understand, add per-domain DoH maps that mirror how your rules already think about traffic, reconcile FakeIP exceptions, and close capture gaps with TUN when needed. Verification stays boring on purpose: reproduce, log, compare, change one variable, repeat. That discipline matters more than any single clever upstream URL.

Generic proxy clients give you either a one-line DNS field or an encyclopedia of toggles with no narrative glue, which is why teams burn weekends reconciling split routes after every OS update. Clash couples a transparent rules language with realistic DNS knobs—nameserver policy included—so advanced users can express intent without forking a custom kernel module. If you want a client that pairs those primitives with approachable profile editing and steady releases, download Clash from our official page, import this pattern alongside the broader DNS leak prevention guide, and iterate until your logs convincingly show each hostname taking the resolver path you designed.

Clash Verge Rev Recommended

Edit Mihomo YAML with confidence: separate nameserver-policy blocks, preview DoH upstreams, and jump from DNS logs to rule hits without losing context when you chase split-resolution bugs.

Policy you can diff

Keep per-domain resolver maps under version control

Readable YAML workflow

Merge provider templates with local DNS overrides safely

Logs that answer “which upstream?”

Trace DoH paths next to rule decisions

Stacked guides

Pair with TUN, FakeIP, and leak-prevention posts on this blog

Previous & Next

Related

Per-domain DoH in one profile

Grab Clash Verge Rev, then layer nameserver-policy over DoH upstreams—keep domestic and overseas resolution paths explicit without maintaining forked configs per device.

Download Free Client