First, distinguish the client, Clash, and mihomo
A Clash client on Windows typically combines a graphical interface, background services, and a proxy core. The interface imports subscriptions, selects proxy groups, and configures the system proxy; the core handles protocol connections, DNS, and rule matching. The same client interface may use different cores across releases. So being able to import YAML does not mean the core supports every field in it.
This article treats the original open-source Clash and Clash Premium as separate projects. Premium was a closed-source enhanced core offered by the original project; it is not the open-source version of Clash. mihomo comes from the Clash Meta project and extends protocol and configuration support. “Clash-compatible” is a common shorthand, not a guarantee of full compatibility across cores.
| Component | Primary role | What to check when migrating |
|---|---|---|
| Original open-source Clash | Provides basic proxy protocols, proxy groups, and rule matching | Don't assume it includes Premium features such as TUN or rule providers |
| Clash Premium | The original project's enhanced core, with features such as rule providers and TUN | Existing rule providers can be checked during migration; Premium scripts should not be assumed to work as mihomo features |
| mihomo / Clash Meta | A core that continues to expand protocol, sniffing, DNS, and rule support | Check subscription fields, the bundled client version, and the core actually in use |
| Windows GUI client | Manages configuration, core processes, the system proxy, and services | The client version shown in the interface is not the mihomo core version |
New protocols: a listed node isn't necessarily usable
One clear difference in mihomo is its broader protocol support. A subscription containing VLESS, Hysteria2, or TUIC cannot simply be used with original Clash or Premium. Support for options within the same protocol can also vary by core and version—for example, transport type, TLS fingerprints, and UDP handling—so check the specific version you're running.
| Protocol or field | Original Clash / Premium | What to check in mihomo |
|---|---|---|
| Shadowsocks、VMess、Trojan | Basic support exists, but supported encryption and transport options vary by version | Check that the encryption method, transport type, TLS settings, and server configuration match |
type: vless | Not supported | Check the UUID and transport. With REALITY, also verify the public key and short-id |
type: hysteria2 | Not supported | Check the authentication details, SNI, port, and whether the server is actually running Hysteria2 |
type: tuic | Not supported | Check the server protocol version, UUID, password, and UDP reachability |
| Shadowsocks 2022 encryption methods | Don't infer support from standard Shadowsocks compatibility | Check the exact encryption method and key format, and use a core version that supports them |
Windows troubleshooting: imported successfully, but nodes won't connect
- Check the
typein the subscription or node details; don't rely on the display name. Labels like “high speed” or “dedicated line” don't tell you which protocol is used. - Check the logs for an unsupported proxy type, unknown encryption method, or missing fields. If the error occurs while parsing the configuration, resolve core compatibility first—repeated speed tests won't help.
- For Hysteria2 and TUIC, make sure your current network allows the relevant UDP traffic. A successful website request over an HTTP proxy doesn't prove that UDP is working.
- If the client lets you choose a core, select a supported mihomo version, restart the core process, and check the startup logs. Renaming a configuration file won't change compatibility.
Switching to mihomo won't fix incorrect server parameters or convert a standard subscription to another protocol. If the server doesn't support the protocol, changing the client-side type alone will make the connection fail.
rule-providers: supported by Premium, with more formats in mihomo
rule-providers aren't unique to mihomo. Clash Premium already supports rule providers; when migrating, compare rule behavior, file formats, and reference order. mihomo also supports the MRS binary format for large domain and IP rule sets, but older cores can't use those files.
Verify references with a local rule set first
This is a snippet for the main configuration, not a complete subscription. It uses the built-in DIRECT and REJECT policies so you can test rules without relying on a particular proxy group name. Store rule-set files in a directory the core can access. Relative paths are resolved from the core's working directory, which may differ from the directory containing the YAML file you opened.
rule-providers:
local-direct:
type: file
behavior: classical
format: yaml
path: ./rules/local-direct.yaml
rules:
- RULE-SET,local-direct,DIRECT
- DOMAIN-SUFFIX,example.org,REJECT
- MATCH,DIRECT
The corresponding rules/local-direct.yaml file should contain the following. Entries in a classical rule set specify match conditions only; they don't include DIRECT. The action is set by the RULE-SET entry in the main configuration.
payload:
- DOMAIN-SUFFIX,example.com
- IP-CIDR,192.168.0.0/16,no-resolve
behavior: domain: Use for domain rules. Don't include completeDOMAIN-SUFFIX,domainrule lines.behavior: ipcidr: Use for IP ranges matched against destination addresses.behavior: classical: Use for traditional rules with rule types; suitable for combining domain, IP, and other conditions.format: mrs: Use for MRS files containing match data. Supported behaviors aredomainandipcidr, notclassical. Changing the file extension does not convert its format.
Rule order matters more than the number of rule sets
Rules are evaluated in order, and the first match determines where a connection goes. If MATCH appears before rule-set references, later rules never get a chance to handle the connection. When adding remote rule sets to a subscription, also make sure the referenced policy group exists; Proxy, PROXY, and localized group names aren't interchangeable.
In the Windows client, add fields through the configuration editor, extended configuration, or override feature, then check configuration validation and logs to confirm the provider loaded. Editing a file generated from a downloaded subscription directly may not survive the next update. For complete rule syntax, see the YAML rule syntax guide.
Sniffing: adds domain clues, not HTTPS decryption
When an app connects directly to an IP address, or the domain-to-IP mapping isn't available to the core's DNS, domain rules may lack the information needed to match. mihomo's sniffer can try to extract domains from HTTP Host headers and server names in TLS handshakes, and can also identify QUIC traffic. This is one of the key configuration differences from original Clash and Premium.
sniffer:
enable: true
override-destination: false
sniff:
HTTP:
ports: [80, 8080-8880]
TLS:
ports: [443, 8443]
QUIC:
ports: [443]
skip-domain:
- "+.lan"
Here, 80, 443, and 8443 are destination ports to sniff—not new local listening ports. The example sets override-destination to false so you can first observe domain detection and rule matching without changing how the connection destination is handled.
Three things to check after enabling it
- Open the client's configuration editor or override settings and add
snifferat the top level. Don't nest it underdnsor inside a proxy node. - After reloading, start a new connection and check the destination domain and matched rule in Connections or the logs. Existing long-lived connections won't be restarted automatically when rules change.
- If a specific intranet service stops working, disable sniffing and test again, then add a bypass for the relevant domain if needed. Avoid enabling several advanced options at once, or it will be harder to tell which one changed the behavior.
DNS fields: keep the basics, then add routing policies as needed
Original Clash already has a DNS module and features such as fake-ip, so using fake IPs doesn't mean you're running mihomo. mihomo adds more options for DNS routing and policies, including proxy-server-nameserver, direct-nameserver, and respect-rules. These fields aren't necessary in every setup.
dns:
enable: true
listen: 127.0.0.1:1053
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
fake-ip-filter:
- "*.lan"
- "localhost"
nameserver:
- 223.5.5.5
proxy-server-nameserver:
- 223.5.5.5
This basic snippet illustrates how the fields relate. 127.0.0.1:1053 listens on the local machine only. 198.18.0.1/16 is used here for fake-IP allocation, not as an upstream DNS server. 223.5.5.5 is an example of unencrypted DNS; it may not suit every network, and it doesn't mean DNS traffic is encrypted.
| Field | Purpose | Common misconception |
|---|---|---|
nameserver | Sets the upstream server for general domain queries | Adding an address here doesn't automatically route every app's DNS through it |
nameserver-policy | Selects a specific upstream server based on match conditions | Controls where DNS queries go, not which proxy node handles application traffic |
proxy-server-nameserver | Provides a dedicated resolver for proxy server hostnames | Changing the regular nameserver may not fix proxy server hostname resolution failures |
direct-nameserver | Sets an upstream resolver for hostnames that need to resolve over a direct connection | You need to understand how direct DNS resolution interacts with policy matching |
respect-rules | Makes connections to DNS upstreams follow routing rules | Use this with proxy-server-nameserver to resolve proxy server hostnames and avoid dependency loops |
On Windows, the system proxy mainly affects apps that honor system proxy settings; it doesn't automatically send all system DNS queries to 1053. If you set only dns.listen without routing queries to that listening port, the setting may not handle any real requests. Apps with built-in encrypted DNS may also connect to their resolvers directly, so check those separately.
Keep the default respect-rules behavior at first and verify regular browsing and node hostname resolution. Add this field only if you need DNS upstream routing, and make sure your rules handle connections to the upstream servers. For other fields, see the DNS configuration guide. Don't combine entire configurations from different guides without checking how they fit together.
TUN and system proxy: enable the traffic entry point separately
mihomo supports TUN, but this isn't a feature newly added over Premium. Their configuration fields and platform implementations aren't interchangeable. On Windows, the system proxy works for apps such as browsers that honor proxy settings. TUN routes more IP traffic through a virtual network adapter and typically requires a client service or administrator privileges.
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
This is only a TUN snippet; it requires the core's DNS to be enabled. any:53 handles traditional DNS requests entering through TUN; it doesn't automatically capture encrypted queries on other ports, such as DoH or DoT. auto-detect-interface isn't a universal fix for multi-adapter setups. If you use a corporate VPN or virtual machine adapters, check the actual egress interface and routes.
How to enable it in a Windows client
- First verify that nodes and rules work in regular proxy mode, then consider TUN. Enabling a virtual adapter when the basic connection fails will usually add more variables to troubleshoot.
- In the client's Settings, find the service mode options and install or enable the service as prompted. If the client requests elevated permissions, review and grant them.
- Turn on the client's TUN Mode or Virtual Adapter option, then check the logs again. The client may generate the
tunfields itself, so use the merged configuration as the source of truth. - Test a browser and an app that doesn't use the system proxy, then check the connection list to confirm traffic is reaching the core. If something goes wrong, turn off TUN and test again; save the logs before checking the adapter and routes.
Client menus vary, so don't treat the location of a switch in one interface as a core requirement. Available features depend on how the client manages services, the core version, and the final configuration—not just whether the YAML contains enable: true.
Migration checklist: inspect the final config, then test real traffic
When migrating from Premium or an older Clash version to mihomo, keep a copy of the original configuration and enable features in this order: basic proxy, rule sets, DNS, sniffing, then TUN. Premium's script feature shouldn't be treated as equivalent to a mihomo feature of the same name. A client's JavaScript override script belongs to a different layer: it generates or modifies configuration, rather than acting as a core rule script.
Use configuration validation to separate syntax issues from connection issues
Save the file you're testing as config.yaml and run the command below from a separate test directory. For a client setup, validate its merged runtime configuration. Passing the check on the subscription source file doesn't guarantee that the overridden configuration will pass too.
.\mihomo.exe -t -f .\config.yaml
Configuration validation can catch parsing errors, missing references, and some invalid fields, but it can't prove that a node is reachable or guarantee that every invalid or unsupported option will be reported. If validation passes but a feature doesn't work, check the startup logs, final configuration, and actual connection matches.
Test the proxy path on a known port
Assuming the runtime configuration uses mixed-port: 7890 and allows local connections, run the command below in Windows PowerShell. It explicitly uses curl.exe to avoid differences caused by the same-name alias in older PowerShell versions.
Test-NetConnection 127.0.0.1 -Port 7890
curl.exe --proxy http://127.0.0.1:7890 --head --max-time 15 https://example.com/
TcpTestSucceeded: Truemeans only that the local port accepts connections; it doesn't confirm that the remote node is working.- After receiving an HTTP response from the destination site, check the connection log for the matched rule and outbound route. The example site is for testing only—not for measuring speed or determining whether all websites are reachable.
- If the client uses a port other than
7890, first find the actual value in Settings or the final configuration, then update the command. Don't change the port just to match the example. - An HTTP proxy test doesn't cover TUN, app-specific DNS, or UDP traffic; test each separately with a new connection.