01 / Structure
YAML Structure Overview
What makes up a configuration file
A Clash configuration file is essentially a YAML document. After mihomo reads it, the core initializes listening ports and DNS services, then loads proxy nodes, proxy groups, rule sets, and runtime options. Most files can be viewed as six layers: general runtime fields, DNS, nodes or proxy Providers, proxy groups, rule Providers, and rules. Their order in the file usually does not affect parsing, but references follow a clear direction: rules reference proxy groups; proxy groups reference nodes or other proxy groups; Providers supply updatable data to proxy groups and rules.
The minimal skeleton below makes the hierarchy easier to understand. It uses local HTTP and SOCKS ports, defines a manual proxy group, and sends traffic that matches no earlier rule directly. The node address and password in the example are instructional values and cannot be used for a real connection.
port: 7890
socks-port: 7891
allow-lan: false
mode: rule
log-level: info
proxies:
- name: Example-Trojan
type: trojan
server: example.com
port: 443
password: "your-password"
sni: example.com
proxy-groups:
- name: Node Selection
type: select
proxies:
- Example-Trojan
- DIRECT
rules:
- DOMAIN-SUFFIX,example.org,Node Selection
- MATCH,DIRECT
Top-level keys must begin at the start of a line. Child items must use consistent indentation, typically two spaces. YAML does not require exactly two spaces, but indentation at the same level must be consistent; tabs are not suitable for indentation. List items begin with a hyphen, and a half-width colon followed by at least one space separates keys from values. Node and proxy-group names may contain non-Latin characters, but every reference must match exactly, including spaces, capitalization, and punctuation.
Mappings, lists, and scalars
Understanding these three data types makes most configurations much easier to read. A mapping is a set of key-value pairs, such as enable: true under dns:; a list is an ordered sequence, such as one rule per line under rules:; and a scalar is a string, number, Boolean, or null value. Write true and false as Boolean values without quotes. Ports should be numbers. Strings containing colons, hash signs, leading or trailing spaces, or values YAML may interpret as another type should generally be quoted.
A hash sign marks the beginning of a comment. If a password or name contains a hash sign, it must be quoted; otherwise everything after it is discarded as a comment. When the same top-level key appears more than once, parsers may keep the first value, keep the last value, or report an error, so never rely on duplicate keys for overrides. This matters especially when editing subscription files: pasting a new dns: section after the existing dns: section does not merge them.
Name references and load order
A proxy-group name is the final target of a rule. For example, if a rule is written as DOMAIN-SUFFIX,example.org,Auto Select, the configuration must contain a proxy group named “Auto Select” or a built-in action with that name. The core recognizes actions such as DIRECT and REJECT; every other name must be declared under proxy-groups. Proxy groups can reference other proxy groups, but avoid cycles such as A referencing B while B references A.
When a client imports a configuration, it may save the original subscription first, apply local overrides, and then pass the result to the core for parsing. The final configuration shown in the interface may therefore differ from the text returned by the subscription server. When troubleshooting, confirm which configuration is active, whether the latest update succeeded, and whether the client enabled scripts or merge rules. If the goal is simply to import a subscription and make the first connection, there is no need to write an entire YAML file by hand; follow the quick-start guide first.
02 / General
Common fields: ports, mode, and logs
Choosing listening ports
port provides an HTTP proxy port, socks-port provides a SOCKS5 proxy port, and mixed-port accepts both HTTP and SOCKS traffic on one port. On desktop systems, the system proxy commonly uses an HTTP or mixed port; command-line tools that require SOCKS5 can use the SOCKS port. In most cases, mixed-port reduces the number of ports to manage, but if existing scripts are hard-coded to use 7890 and 7891, keep the current port layout.
mixed-port: 7890
allow-lan: false
bind-address: "*"
mode: rule
log-level: info
ipv6: false
Two programs on the same device cannot listen on the same address and port at the same time. When a client reports “address already in use,” close the other proxy application or choose another port; do not blame the node. Port numbers range from 1 to 65535, and low-numbered ports may require additional permissions on some desktop systems. After changing a port, update the proxy address in browsers, terminal environment variables, and devices on the local network.
LAN access and bind addresses
allow-lan controls whether other devices can access the proxy ports exposed by the current device. Set it to false for local-only use to reduce unnecessary exposure. To connect a computer, TV, or test device on the same Wi-Fi network, set it to true and use the proxy host’s LAN address. Also confirm that the system firewall allows the port and that the devices can communicate, and avoid enabling this on public networks.
bind-address determines which local addresses accept connections. An asterisk usually means all available interfaces, while a loopback address restricts access to the local device. Different clients may manage these parameters through their UI; an “Allow LAN” switch may generate the corresponding field at runtime. iOS network extensions work differently from desktop port proxies, and importing the same configuration does not necessarily expose listening ports to other devices. For cross-device sharing, rely on the client’s actual capabilities.
rule, global, and direct modes
mode: rule determines the route for each connection by checking the rule list from top to bottom, making it the most common mode for everyday use. global sends all traffic to the global proxy group, which is useful for briefly checking whether a node works but does not show the outcome of detailed rules. direct connects to destinations directly and can help compare network behavior with and without a proxy. Switching modes only changes the traffic-routing entry point; it does not repair invalid nodes or incorrect DNS automatically.
When the client offers “Rule,” “Global,” and “Direct” modes, the UI selection usually overrides the default mode in the configuration file. When rules appear ineffective, check both the YAML and the current UI state. If the client remains in global mode, changing rules will naturally show no difference; in direct mode, node selection in proxy groups will not handle most traffic.
| Field | Common values | Purpose | Troubleshooting focus |
|---|---|---|---|
mixed-port |
7890 | Accept HTTP and SOCKS proxy traffic on one port | Port conflict or caller still using the old port |
allow-lan |
true / false | Control access from LAN devices | Firewall, network isolation, and bind address |
mode |
rule / global / direct | Choose the traffic-routing mode | The UI may override the file’s default value |
log-level |
info / warning / error | Control runtime log verbosity | Restore a moderate log level after troubleshooting |
ipv6 |
true / false | Control IPv6 handling | Whether the local network actually has IPv6 connectivity |
Logs, the control interface, and configuration storage
log-level commonly uses info, which shows connections, rule matches, and some errors. Too little logging makes problems difficult to locate, while keeping verbose debug output enabled permanently makes logs harder to read. When a connection fails, record the target domain, matched rule, selected proxy group, and error type before changing the configuration; do not repeatedly change every setting based only on the fact that a page will not open.
external-controller provides an API for compatible control interfaces, such as one listening on the local loopback address. If secret is set, the control client must use matching credentials. Mobile clients usually manage the control interface themselves, so do not expose it to the LAN just to follow a desktop tutorial. Use your own credentials and never publicly paste a complete configuration containing subscription URLs, node passwords, or control keys.
Storage options under profile can preserve proxy-group selections or Fake IP mappings. Whether and when these options are supported depends on how the client integrates the core. After upgrading a client or changing configurations, if a proxy group still uses an old selection, first check whether selection persistence is enabled before assuming the configuration failed to refresh. See the download page for platform requirements and available clients.
03 / DNS
DNS configuration: resolution paths and hijacking
What the DNS section does
The DNS section determines how domains are resolved into addresses and whether the core takes control of DNS requests. A working proxy node does not guarantee correct DNS: the system network may still resolve domains directly, or a router, carrier network, or another VPN may take over. Typical symptoms include some domains failing to open, unexpected rule matches, brief problems after switching networks, or an app reporting no access even though the proxy is connected.
dns:
enable: true
listen: 0.0.0.0:1053
ipv6: false
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
use-hosts: true
nameserver:
- https://1.1.1.1/dns-query
- https://8.8.8.8/dns-query
proxy-server-nameserver:
- 223.5.5.5
fake-ip-filter:
- "*.lan"
- "localhost.ptlogin2.qq.com"
enable controls whether the built-in DNS is enabled. listen is the address on which the DNS service listens; on desktops or routers it may be used for system forwarding, while mobile devices are usually handled by a network extension. Do not judge whether DNS works solely by checking a listening port. ipv6 controls whether AAAA results are returned and processed. If the local IPv6 path is unstable, temporarily disabling it can help determine whether dual-stack networking is involved, but disabling IPv6 is not a universal fix for DNS problems.
The relationship between nameserver and bootstrap
nameserver is the list of primary resolvers. It can contain traditional UDP addresses or encrypted DNS URLs. With DoH, the DoH server’s own domain must also be resolved first, creating a dependency during startup. Depending on the configuration style supported by mihomo, default-nameserver or dedicated resolver settings can handle this initial lookup. Use resolvers reachable directly by IP here to avoid depending on a proxy path that has not been established yet.
proxy-server-nameserver is mainly used to resolve proxy server hostnames. Keeping it separate from ordinary destination lookups helps avoid the circular dependency where the client must connect to a proxy server before it can resolve that server’s hostname. If a node’s server is already an IP address, this matters less; when a subscription contains many hostname-based nodes, a set of resolvers directly reachable on the current network is safer.
Encrypted DNS does not automatically mean every query travels through a proxy. A resolver URL may be reached directly or routed through a policy, depending on the address parameters supported by the core. When designing a DNS path, define the goal first: avoiding local resolver interference, getting consistent results for rule matching, or sending certain domains to a specific resolver. Different goals require different configurations. Do not pile in many public DNS services and expect the core to choose the best one automatically; differing responses can make behavior less predictable.
fake-ip and redir-host
In fake-ip mode, the application first receives a mapped address from a reserved pool. The core then restores the original domain from the mapping and applies rules. This preserves domain information for matching and works directly in transparent-proxy scenarios. redir-host returns the real resolved address instead. Some LAN services or applications sensitive to address behavior may be more compatible with it, but domain preservation and matching follow a different path.
fake-ip-range should use a dedicated address range that does not overlap with networks used by home or corporate LANs, containers, or VPNs. If a LAN domain returns a Fake IP, it was not excluded. Add domains that clearly require real resolution to fake-ip-filter, such as LAN suffixes, device-discovery domains, or specific login domains. Keep filter entries as specific as possible; overly broad wildcards let many requests bypass Fake IP and weaken unified interception.
nameserver-policy and split DNS
nameserver-policy lets specific domains or rule sets use designated resolvers. For example, internal domains can go to a corporate DNS server while other domains use a public encrypted resolver. More specific matchers are easier to maintain. If a domain matches multiple policies, check the core’s matching priority and confirm the result in logs rather than inferring it from the order of entries alone.
dns:
enable: true
enhanced-mode: fake-ip
nameserver:
- https://1.1.1.1/dns-query
nameserver-policy:
"geosite:cn":
- https://223.5.5.5/dns-query
"+.internal.example":
- 192.168.1.1
fake-ip-filter:
- "+.internal.example"
- "*.lan"
Internal resolvers are often reachable only on a particular Wi-Fi network, corporate network, or VPN. After leaving that network, a policy that still sends internal domains to an unreachable address will time out. Because mobile devices frequently switch between cellular data and Wi-Fi, place this kind of configuration behind the appropriate on-demand connection condition or in a separate configuration instead of letting a work-network-specific DNS setup govern every situation.
DNS troubleshooting order
First test the same target by domain and by IP: if the IP works but the domain fails, focus on resolution; if both fail, inspect the proxy group, node, and system network. Next, check logs for DNS timeouts, connection refusals, or resolver handshake errors. Then confirm that no other VPN, Private DNS setting, filtering app, or router DNS rewrite is active. Only afterward adjust enhanced mode, resolvers, or IPv6. Change one variable at a time, and clear short-term app or system caches before retesting.
If the symptom is “connected but no internet,” read the top-to-bottom troubleshooting checklist. For a field-by-field explanation of fallback, filtering, and DNS hijacking, continue with the detailed DNS guide. Clients may wrap some fields in a graphical interface; the runtime logs and exported active configuration are the final authority.
04 / Proxies
Proxy node fields
Common fields and reference names
proxies is a static list of nodes. Each node requires at least name, type, server, and port; the remaining fields depend on the protocol. name is an internal reference identifier and does not establish the network connection; server is the server hostname or address. Proxy groups refer to nodes by name, so renaming a node requires updating every proxy group that references it directly.
Node names should be short and stable. If the service changes a name during a subscription update, a remembered proxy-group selection may no longer find the old item and may fall back to the default node. For long-term stable selection, let a proxy group use a Provider with filters to select a category of nodes, or keep naming consistent through a local override. Do not infer route quality from a region label in the name; actual availability also depends on the local network, entry point, transport settings, and server status.
Trojan example
proxies:
- name: Example-Trojan
type: trojan
server: edge.example.com
port: 443
password: "your-password"
sni: edge.example.com
udp: true
skip-cert-verify: false
Trojan commonly uses TLS. sni is the server name sent during the TLS handshake and should match the server certificate and deployment. password must preserve all special characters; quoting it is safer. udp controls whether the node carries UDP traffic, but it works only when the client, core, and server all support it. Setting skip-cert-verify disables certificate verification and weakens identity checks. A normal deployment should keep it false; fix certificate errors by checking the server name, certificate validity, system clock, and possible network interference.
Shadowsocks example
proxies:
- name: Example-SS
type: ss
server: 203.0.113.10
port: 8388
cipher: aes-128-gcm
password: "your-password"
udp: true
The key Shadowsocks fields are the cipher and password, and both ends must match. Do not replace cipher based on personal preference; enter the method configured on the server. When a connection fails, verify the address, port, method, and password, then check whether the server firewall and local network allow the traffic. Copying fields from another protocol does not improve compatibility. Unrecognized fields may be ignored or may cause configuration validation to fail.
VMess, VLESS, and transport-layer settings
VMess commonly uses fields such as uuid, alterId, and cipher. VLESS uses a UUID and may use TLS, Reality, or other transport settings depending on the deployment. WebSocket and gRPC transports often add a path, Host, service name, and request headers. Field nesting must match the format supported by mihomo; do not copy JSON fields exported by another client verbatim into YAML.
- name: Example-VMess-WS
type: vmess
server: ws.example.com
port: 443
uuid: 00000000-0000-4000-8000-000000000000
alterId: 0
cipher: auto
tls: true
servername: ws.example.com
network: ws
ws-opts:
path: /network
headers:
Host: ws.example.com
Here, server determines the connection target, while servername or the corresponding SNI field affects TLS, and the WebSocket Host affects the application-layer request. These three hostnames may be identical in a simple deployment but different when a reverse proxy or separate entry points are used. A typo in any one of them can look like a TCP connection that succeeds but a handshake that fails. Troubleshoot layer by layer: DNS resolution, TCP port, TLS, transport, then protocol authentication.
Node-level network options
interface-name can specify the outgoing network interface, while routing-mark is commonly used for Linux policy routing; mobile clients generally do not require manual settings. Options such as ip-version and prefer-ipv6 affect how the node’s server hostname is resolved, with exact support depending on the core. Adjust them only after confirming that dual-stack resolution selected the wrong address; do not mistake an ordinary route failure for an IP-version problem.
If the node fields are correct but the node still does not work, place it in a simple select group and temporarily switch to global mode to rule out complex rules. Return to rule mode after testing. If every node fails at once, check the subscription status, system clock, DNS, and local network first; only a single failed node warrants focused protocol-parameter checks. See the download page for client and platform differences. Clash Plus is the top cross-platform recommendation for establishing a basic connection before fine-tuning the configuration.
05 / Policy
Proxy-group fields and selection logic
select: leave the choice to the user
Proxy groups sit between nodes and rules. Rules generally point to a proxy group rather than a specific node; when you change the group’s selection in the client, every rule targeting that group uses the new result. select is a manually controlled group, suitable for clear entry points such as “Node Selection,” “Streaming,” and “Downloads.” A group can contain nodes, other proxy groups, or DIRECT.
proxy-groups:
- name: Node Selection
type: select
proxies:
- Auto Select
- Failover
- Example-Trojan
- DIRECT
List order affects the default shown in the UI and the fallback experience. Put the most frequently used choice first, but never create a cycle between upper- and lower-level groups. For example, having “Node Selection” contain “Auto Select” is reasonable; having “Auto Select” also use “Node Selection” as a candidate creates a cycle that cannot be parsed or executed. For complex configurations, draw the reference direction first and then define the layers.
url-test: select automatically based on probe results
url-test checks candidate nodes against a specified URL and selects a suitable result. It measures request performance to the test target, not the actual speed of every website. Use a stable URL with a small response body that represents the networks you mainly use. Testing too frequently increases background activity and server requests, and may consume more battery on mobile devices.
- name: Auto Select
type: url-test
proxies:
- Example-Trojan
- Example-SS
url: https://www.gstatic.com/generate_204
interval: 600
tolerance: 80
lazy: true
interval is the test interval, usually in seconds; tolerance prevents frequent switching when candidates differ only slightly; lazy can make tests run closer to on demand. Configure these fields for stability rather than constant refreshing. If a service requires a consistent exit point, frequent node changes may disrupt sessions, so increase the tolerance and interval or use a manual group.
fallback and load-balance
fallback uses nodes in list order and moves to the next candidate when the current node fails its probe. It suits a “preferred route first, switch only when unavailable” setup. Unlike url-test, it does not optimize solely for the lowest test result; it preserves the preferred order. If traffic always falls back to the second node, check whether the preferred node can reach the test URL instead of checking only ordinary webpages.
load-balance distributes different connections across multiple nodes according to a policy. It does not simply add the bandwidth of one download together, and changing exit addresses can affect login sessions, risk controls, or long-lived connections. Sites that require a consistent source address are not good candidates for casual load balancing. Policies may distribute connections by hash or round robin; understand the fields supported by the client’s current core before choosing one.
| Group type | Selection method | Suitable use | Main consideration |
|---|---|---|---|
select |
Manual | When the exit point must be controlled explicitly | Remembered selections may break after nodes are renamed |
url-test |
Automatic selection after probing | Automatically choose the best among similar nodes | Test results do not represent the speed of every destination |
fallback |
Fail over in order | A preferred route with backup routes | The test target must remain reliably reachable |
load-balance |
Distribute different connections | Concurrent requests where multiple exit points are acceptable | Login sessions and exit-address consistency |
Select nodes through a Provider
When nodes come from proxy-providers, a proxy group can reference a Provider with use instead of listing every node name under proxies. When a subscription adds or removes nodes, the group’s candidates update accordingly. You can also use filter to select nodes by name, such as including only names containing a regional label. Filters commonly use regular expressions, so account for capitalization, full-width characters, and server-side renaming.
- name: Mobile Network
type: select
use:
- provider-main
filter: "(?i)mobile|Mobile"
exclude-filter: "(?i)expire|remaining|expired"
Name filters examine text only; they do not verify a node’s actual location, protocol, or route characteristics. If the subscription naming convention changes, a group may suddenly become empty. Give important groups visible fallback entries and check the candidate count after each subscription update. If the client shows an empty group, first check whether the Provider update succeeded, then the filter expression, and finally the Provider name.
Avoid making proxy-group designs unnecessarily deep. Three common layers cover most needs: a lower layer of node pools and automatic test groups, a middle layer with a general entry point such as “Node Selection,” and an upper layer for video, downloads, or specific services. The more layers there are, the harder it is to trace the final exit in logs. After a rule matches, verify each step: “rule target group → current group selection → lower-level group selection → specific node.”
06 / Rules
Rule syntax and matching order
Match from top to bottom; stop at the first match
rules is an ordered list. The core checks connections from the first rule onward and stops after a match, applying that rule’s policy. Put specific rules before broad rules, with the final fallback at the end. If MATCH appears too early, later domain and address rules never run. When a rule appears ineffective, first check which rule the logs actually matched instead of adding more duplicates.
rules:
- DOMAIN,api.example.com,Node Selection
- DOMAIN-SUFFIX,example.com,Node Selection
- DOMAIN-KEYWORD,example,Node Selection
- IP-CIDR,203.0.113.0/24,DIRECT,no-resolve
- GEOIP,CN,DIRECT
- MATCH,Node Selection
A classic rule usually consists of a rule type, match value, and policy target separated by half-width commas. The policy target must be an existing proxy group, node name, or built-in action. Extra spaces in a rule line may become part of the value, so keep formatting consistent. Domain matching does not include URL paths; routing by webpage path cannot be done with DOMAIN rules alone.
DOMAIN, DOMAIN-SUFFIX, and DOMAIN-KEYWORD
DOMAIN matches a complete hostname exactly. For example, DOMAIN,api.example.com matches only that host and does not automatically include www.example.com. DOMAIN-SUFFIX,example.com matches the root domain and its subdomains, making it suitable for a group of hosts belonging to one service. DOMAIN-KEYWORD may match whenever the specified text appears in a domain, so its scope is broad and it can easily catch unrelated sites with similar names.
Prefer exact domains and suffixes when designing rules, and use keywords only when the domain set genuinely cannot be organized. A service may depend on several domains for login, APIs, images, and media; handling only the main webpage domain may not cover all requests. Observe connection logs and expand coverage gradually, but do not hard-code every temporary CDN hostname into the main configuration. Large domain collections are better suited to a rule-set Provider.
IP-CIDR and no-resolve
IP-CIDR matches IPv4 networks, while IP-CIDR6 matches IPv6 networks. The suffix after CIDR indicates the network prefix length; for example, /24 covers a contiguous range of IPv4 addresses. IP rules cannot reliably represent cloud-service domains that change frequently, so do not treat an address resolved once as a permanent rule. IP rules are most appropriate for stable provider ranges, LAN addresses, or clearly defined networks.
no-resolve means the core should not trigger an additional domain lookup to evaluate the IP rule. When a connection already has a destination IP, it can be matched directly; when only a domain is available, the core will not resolve it specifically for this rule. This reduces unnecessary queries and possible loops, but it can also prevent IP rules that depend on a resolved address from matching. Decide whether to use it based on the information available when the request enters the core.
rules:
- IP-CIDR,127.0.0.0/8,DIRECT,no-resolve
- IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
- IP-CIDR,172.16.0.0/12,DIRECT,no-resolve
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- IP-CIDR6,::1/128,DIRECT,no-resolve
Put LAN direct-connection rules near the top to keep printers, routers, and file servers out of remote proxies. Corporate networks may use larger private address plans, and home networks may overlap with VPN ranges. When a LAN service is unreachable, confirm the actual destination address first, then determine whether the problem is a rule error, insufficient Fake IP filtering, or a system route that does not point to the local interface.
GEOIP, GEOSITE, and rule sets
GEOIP classifies a destination by the country or region associated with its IP in a database, which is useful for regional IP routing but does not identify business ownership. A local brand may use cloud nodes in another region, while an overseas service may deploy edge addresses locally. GEOSITE uses domain-category data, and its coverage depends on the rule database. Both rely on data updates and should not be treated as permanently accurate facts.
mihomo commonly uses RULE-SET for rule-set matching. A rule set can contain domain, ipcidr, or classical data, and the reference must match the Provider’s behavior. Putting complete classical rules in a domain-behavior rule set, or using the wrong behavior for an IP rule set, can cause parsing failures or unexpected matches.
Process rules and platform limitations
PROCESS-NAME, PROCESS-PATH, and similar process rules depend on process information supplied by the operating system. They may work on desktop systems with the required permissions, but iOS network extensions generally cannot read arbitrary process paths the way desktop clients can. When writing cross-platform configurations, do not make critical routing depend entirely on process rules. Domains, IPs, and rule sets are a safer foundation, with process rules as an addition for specific desktop environments.
The same configuration may behave differently on Windows, macOS, Android, and iOS. The cause is usually not a change in YAML syntax but differences in system interception, permissions, and network stacks. Put platform-specific rules in local overrides and keep the subscription body general. This prevents desktop-only process rules from being forced onto mobile devices during subscription updates.
REJECT, DIRECT, and the final fallback
DIRECT connects directly, while REJECT denies the connection. Blocking rules should be precise; broad keywords or domain suffixes can interrupt login, payment, and essential API requests. The final rule usually uses MATCH to point to a general proxy group or direct connection, depending on the goal. Without a final fallback, unmatched traffic may follow the core’s default behavior, leaving the configuration’s intent unclear.
After changing rules, test the main branches: one domain that should be direct, one that should use a proxy, one LAN address, and one rule-set target. Testing a single webpage cannot prove that the complete rule chain is correct. For speed problems, distinguish the node, route, and local settings. See the three-layer guide to troubleshooting slow speeds instead of attributing every performance issue to the number of rules.
07 / Providers
Proxy Providers and Rule Providers
Why use Providers
Providers separate frequently changing data from the main configuration. proxy-providers supplies node lists, while rule-providers supplies rule collections. The main configuration handles names, update intervals, and policies; remote files provide the actual content. This avoids rewriting the entire main configuration when a subscription updates and lets multiple proxy groups share one node pool.
Provider URLs often contain access credentials, so treat the complete configuration as sensitive data. When troubleshooting, you can share the structure after removing credentials, but never publish a real subscription URL. If a remote file is unavailable, the client may continue using its local cache or leave the related group empty after an initial download failure. Old nodes remaining visible does not necessarily mean the update succeeded; check the update time and Provider logs.
Proxy Provider configuration
proxy-providers:
provider-main:
type: http
url: "https://subscription.example/path?token=xxxx"
path: ./providers/provider-main.yaml
interval: 21600
health-check:
enable: true
url: https://www.gstatic.com/generate_204
interval: 900
lazy: true
type: http means the resource is fetched remotely, url is the resource address, path is the local cache path, and interval controls the update interval. Give each Provider its own path to prevent updates from overwriting one another. In a sandboxed client, the app controls the actual storage location; relative paths are usually resolved from the core’s working directory, so do not copy desktop absolute paths directly.
health-check checks the availability of nodes supplied by a Provider. It does not automatically change every proxy-group selection; only groups such as url-test and fallback use probe results for their decisions. Balance check frequency against responsiveness and background cost. On an iPhone, many Providers with frequent checks increase the workload of the network extension. Adjust the settings according to on-demand connections and actual usage.
A Provider response must use the proxy-provider format, not a complete Clash configuration. Common content begins with proxies: and contains a node list. If the remote server returns an HTML login page, an error message, or ordinary text, it cannot be parsed even when the HTTP status appears successful. When an update fails, check the response content type, redirects, access permissions, and system clock.
Rule Provider configuration
rule-providers:
private-network:
type: http
behavior: ipcidr
format: yaml
path: ./rules/private-network.yaml
url: "https://rules.example/private-network.yaml"
interval: 86400
service-domains:
type: http
behavior: domain
format: yaml
path: ./rules/service-domains.yaml
url: "https://rules.example/service-domains.yaml"
interval: 86400
rules:
- RULE-SET,private-network,DIRECT,no-resolve
- RULE-SET,service-domains,Node Selection
- MATCH,Node Selection
behavior determines how rule-set entries are interpreted. domain is for domain collections, ipcidr is for address ranges, and classical can contain classic rules with types and parameters. format must match the remote file. YAML rule sets usually wrap the list in payload:; text and binary rule sets use their corresponding formats. A file extension alone does not prove the content format; the actual data structure is what matters.
payload:
- "+.example.com"
- "api.example.net"
- "*.service.example"
Wildcard syntax in a domain-behavior rule set must follow mihomo rule-set semantics; do not mix browser matching patterns or regular expressions into it directly. A classical rule set can contain complete entries such as DOMAIN-SUFFIX,example.com. If you add no-resolve when referencing a set, confirm that it uses IP behavior and does not require an additional lookup.
Updates, caching, and fallback
Provider updates should be observable as an independent step. When nodes suddenly disappear, first check whether the remote file changed, then inspect filters and proxy-group references. When rule behavior changes unexpectedly, record the rule-set update time and check whether the data source changed its classifications. Blaming every issue on the main configuration overlooks changes in external data.
The first run must be able to retrieve Provider files; otherwise groups or rule sets that reference them cannot be built completely. Existing caches are suitable only as temporary fallbacks and should not hide a dead URL indefinitely. If a remote file is unreachable, update it again when the network allows and then enable the related configuration. You can also keep essential LAN and final-fallback rules in the main configuration so basic connectivity does not depend entirely on external rule sets.
A shorter update interval is not always better. Node subscriptions may update several times a day, while stable rule sets may need one update per day or less. Frequent updates increase requests, writes, and parsing, with little benefit on mobile networks. When an update fails, check in this order: the address is reachable, the response content is correct, the local path is writable, the format matches behavior, and the reference name is correct.
08 / Override
Overrides, merging, and configuration troubleshooting
Subscriptions, local overrides, and the final configuration
Most clients do not run the raw subscription directly. A common flow is to download the subscription, parse the base configuration, apply local overrides or scripts, generate the final configuration, and then pass it to the mihomo core. This distinction matters: a rule visible on the subscription webpage may not remain unchanged in the active configuration, and locally edited fields may be replaced at the next subscription update.
Content maintained by the service, such as nodes, base proxy groups, and standard rules, belongs in the subscription. Content specific to a device or user, such as ports, the LAN switch, device-specific DNS, personal rules, and platform differences, belongs in local overrides. Do not maintain extensive personal edits directly in an automatically updated subscription file or every update will require another manual comparison.
Replacement is not the same as deep merging
Replacement usually means the new value takes the place of the old one; deep merging continues inside mappings and replaces only specified child keys. Lists vary even more: some merge tools replace the entire list, while others support prepending, appending, or editing by name. Do not infer behavior from the word “merge” alone. Read the client’s override documentation and export the final configuration to confirm.
# Base configuration
dns:
enable: true
enhanced-mode: fake-ip
nameserver:
- https://1.1.1.1/dns-query
# Requested changes
dns:
ipv6: false
nameserver:
- https://8.8.8.8/dns-query
With a deep merge, the final DNS section might retain enable and enhanced-mode while replacing ipv6 and nameserver. With top-level replacement, the original DNS section might disappear entirely, leaving only the two fields from the override. If lists are appended, both nameserver entries may remain. Only the final result reveals which semantics the client uses.
Prepending, appending, and removing rules
Personal rules usually need to be prepended before subscription rules because matching stops immediately. For example, to send an internal domain directly, place it before a broad proxy rule that could also match it. Appending it after MATCH has no effect. If the override tool supports prepend and append, put precise exceptions in prepend and leave the final fallback to the main configuration.
# Logic example: prepend rules
rules-prepend:
- DOMAIN,router.example,DIRECT
- DOMAIN-SUFFIX,internal.example,DIRECT
# Logic example: content after MATCH cannot take effect
rules-append:
- DOMAIN-SUFFIX,archive.example,Node Selection
The key names above illustrate merge logic and are not recognized directly by every client. In practice, use the client’s override interface or the keys specified in its documentation. Removing rules is more sensitive to text differences than adding them: different spaces, proxy-group names, or parameters can make an exact deletion fail. A safer approach is to prepend a more specific rule that overrides the old result instead of relying on fragile string deletion.
Find problems with a minimal configuration
When a complex configuration fails, do not change DNS, nodes, proxy groups, and rules all at once. Create a minimal configuration with one known-good node, one select group, and one MATCH rule. If it connects, the problem is in a removed layer; add sections back one at a time in this order: DNS, Providers, proxy groups, then rules. If the minimal configuration still fails, focus on node parameters, system permissions, and the current network.
mixed-port: 7890
mode: rule
log-level: info
proxies:
- name: Test
type: trojan
server: example.com
port: 443
password: "your-password"
sni: example.com
proxy-groups:
- name: TEST
type: select
proxies:
- Test
- DIRECT
rules:
- MATCH,TEST
When testing on mobile, also account for the system VPN state. Close other apps that may be using a network extension, re-enable the current configuration, and check whether the client successfully establishes the system VPN. If Wi-Fi works but cellular data fails, check the app’s cellular-data permission, on-demand connection conditions, and DNS reachability. If only one Wi-Fi network fails, check its captive portal, router filtering, and private-address policy.
Handle issues by error type
| Symptom | First layer to check | Next step |
|---|---|---|
| The configuration cannot load and shows a line number | YAML indentation, duplicate keys, and quotes | Inspect the reported line and the indentation of its parent level |
| The proxy group is empty | Provider update, use name, and filter | Remove the filter and inspect the remote content |
| Rules consistently hit the wrong target | Mode, rule order, and MATCH position | Use connection logs to confirm the first matching rule |
| The domain fails but the IP is reachable | DNS and Fake IP | Test resolvers and inspect filter entries |
| A single node fails during the handshake | Node protocol, TLS, and transport layer | Check server, SNI, and path one by one |
| All nodes become unavailable at once | Subscription, system clock, and local network | Use a minimal configuration and compare across networks |
Saving, rollback, and change records
Before making changes, keep a known-working configuration and give local copies clear filenames. Change one category of fields at a time, recording the purpose and test result. If something breaks, returning to the last working copy is more reliable than trying to undo several edits from memory. Subscription URLs and node credentials should never enter a public code repository; when documenting the structure, replace servers, passwords, and access parameters with clearly fictional teaching values.
After editing, run a four-layer check. Layer one is YAML: indentation, colons, lists, and duplicate keys. Layer two is references: proxy groups, Providers, and rule targets must use consistent names. Layer three is runtime: ports must not conflict, and DNS and Providers must load. Layer four is behavior: direct, proxied, LAN, and final-fallback traffic must each match the expected result. The configuration is complete only when all four layers pass.
From the reference manual back to practical use
If the goal is simply to make the first connection, return to the user guide and follow the steps to import a subscription, choose a mode, connect, and verify the result. To install or switch clients, use the download page to choose the Windows, Android, iOS, macOS, or Linux entry point. If the configuration loads but webpages still show certificate warnings, read what causes HTTPS certificate errors and how to handle them. For unusually high background battery use on iPhone, see how network extensions work in the background and how to save power.
Configuration maintenance is not about putting every field in one file. It is about keeping references clear, update sources traceable, and platform differences isolated. The main configuration provides stable structure, Providers supply updatable data, and local overrides handle device and personal needs. When something goes wrong, narrow the scope layer by layer—YAML, DNS, nodes, proxy groups, rules, and the system network—instead of replacing the entire configuration.