Start with YAML’s hierarchy and parsing rules
Clash configuration files typically use YAML. They are not a series of unrelated switches, but a hierarchical configuration tree: top-level fields control core behavior, indented fields belong to the object above them, and entries beginning with a hyphen are list items. When reading a config, check indentation first, then interpret each field. Looking only at field names without their level can easily place a valid parameter in the wrong location.
Indentation, colons, and lists
- Use spaces consistently for indentation. Two spaces per level is common; do not mix in tabs.
- Put a space after the colon in a key, such as
mode: rule. - Fields such as
dns:andprofile:have nested items below them, and those items must be indented further. proxies:,proxy-groups:, andrules:usually contain lists, with each item beginning with-.- Names containing special characters such as colons, hash signs, or braces should be wrapped in single or double quotes.
mode: rule
log-level: info
profile:
store-selected: true
store-fake-ip: true
proxy-groups:
- name: 'Proxy Selection'
type: select
proxies:
- 'Auto Select'
- DIRECT
In the example above, store-selected belongs to profile, while name, type, and proxies together form a proxy-group object. If the indentation of type and name does not align, YAML may still parse but produce a completely different data structure.
Common fields: ports, LAN access, and operating mode
The beginning of a config commonly defines listening ports, operating mode, log level, and the controller port. These fields determine how the application receives system traffic and how a GUI client communicates with the Clash Meta (mihomo) core.
port: 7890
socks-port: 7891
mixed-port: 7893
redir-port: 7892
tproxy-port: 7895
allow-lan: false
bind-address: '*'
mode: rule
log-level: info
ipv6: false
external-controller: 127.0.0.1:9090
secret: 'change-this-controller-secret'
What traffic does each port handle?
port- HTTP proxy listening port. The address in examples is usually
127.0.0.1:7890. socks-port- SOCKS5 proxy port. Command-line tools or applications that support SOCKS5 can connect to
127.0.0.1:7891. mixed-port- Accepts HTTP and SOCKS5 requests on the same port. Keep this option when the client only needs to expose one local proxy endpoint.
redir-port- Used for Linux redirection setups, typically together with iptables or compatible traffic-forwarding rules.
tproxy-port- Used for Linux TPROXY transparent proxying, handling forwarded traffic that needs to preserve its destination address.
You do not need to enable every port. For desktop clients using the system proxy, a common setup enables only mixed-port: 7890, or enables separate HTTP and SOCKS ports. If the log shows address already in use, check whether another proxy, an old core process, or a development service is already using the port before changing the config or stopping the conflicting process.
mode, allow-lan, and the controller interface
mode: rulematchesrulesfrom top to bottom and is the most common mode for everyday traffic splitting.mode: globalsends connections to the global proxy group instead of applying ordinary rules one by one.mode: directconnects directly, which is useful for checking whether a problem comes from the proxy chain.allow-lan: truelets devices on the local network connect to the listening port. Also check the system firewall, bind address, and trusted network boundary when enabling it.external-controlleris the REST API controller interface. For local-only use, bind it to127.0.0.1; for a remote dashboard, set a validsecretand restrict network access.
bind-address: '*' listens on available addresses, but whether it is actually exposed to the LAN is controlled by allow-lan and the firewall. Do not treat the bind address, LAN access, and controller interface as the same setting: they manage the proxy entry point, LAN permission, and core management API respectively.
DNS: resolution paths and Fake-IP
DNS settings determine how domains are resolved and can affect whether domain rules continue matching when a connection is made. Common enhanced modes in Clash Meta (mihomo) include fake-ip and redir-host. The former returns a mapped address from a reserved range while the core maintains the domain-to-connection mapping; the latter is closer to returning the real resolution result.
dns:
enable: true
listen: 127.0.0.1:1053
ipv6: false
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
fake-ip-filter:
- '*.lan'
- '*.local'
- 'time.*.com'
- 'time.*.gov'
default-nameserver:
- 223.5.5.5
- 119.29.29.29
nameserver:
- 'https://dns.alidns.com/dns-query'
- 'https://doh.pub/dns-query'
fallback:
- 'https://1.1.1.1/dns-query'
- 'https://dns.google/dns-query'
fallback-filter:
geoip: true
geoip-code: CN
The roles of the three nameserver types
default-nameserverusually contains directly reachable IP addresses used to resolve the hostnames of DoH or DoT servers themselves, avoiding a circular dependency during startup.nameserveris the primary resolver. It can use ordinary UDP DNS or encrypted resolvers such as DoH and DoT.fallbackprovides backup resolvers. Whether its results are used depends on conditions such asfallback-filter.
listen: 127.0.0.1:1053 makes the DNS listener accessible only from the local machine. If the client already takes over system DNS automatically, you usually do not need to point the operating system’s DNS to this port manually. In TUN mode, the core may also receive port 53 requests through DNS hijacking; the exact behavior depends on the TUN config generated by the client.
What belongs in fake-ip-filter?
LAN domains, device-discovery domains, some time-synchronization domains, and application domains that require real addresses can be added to fake-ip-filter. Avoid adding broad wildcards indiscriminately: many domains would bypass Fake-IP mapping, changing domain-rule matching and first-connection latency.
proxies: defining individual nodes
proxies is a static list of nodes. Each node needs at least a name, protocol type, server address, and port; protocol-specific authentication and transport fields come next. Node fields must match the server’s actual setup. Sharing a protocol name does not mean the port, encryption, TLS hostname, or WebSocket path can be interchanged.
proxies:
- name: 'Example-Trojan'
type: trojan
server: edge.example.com
port: 443
password: 'example-password'
udp: true
sni: edge.example.com
skip-cert-verify: false
- name: 'Example-VMess'
type: vmess
server: vm.example.com
port: 443
uuid: 00000000-0000-4000-8000-000000000001
alterId: 0
cipher: auto
udp: true
tls: true
servername: vm.example.com
network: ws
ws-opts:
path: /connect
headers:
Host: vm.example.com
Node names are reference keys
name is more than display text: proxy groups reference nodes using the exact same string. If a node is named Example-Trojan, writing Example Trojan in a proxy group creates a reference to a node that does not exist. When renaming a node, check every proxy-groups, rule target, and chained-proxy setting.
TLS and transport fields must match
serveris the server address used to establish the connection.sniorservernamesupplies the server name for the TLS handshake and should match the value provided by the node operator.skip-cert-verify: falseenables normal server-certificate verification.network: wsselects WebSocket transport, with its parameters underws-opts.udp: trueallows the node to handle UDP. Actual connectivity still depends on the protocol, server, and network environment.
When importing a subscription, nodes are often not written directly under proxies. The client may generate them after conversion or load them through proxy-providers. Both approaches can coexist, but duplicate node names make proxy-group references and troubleshooting harder.
proxy-providers and proxy-groups: from nodes to policies
proxy-providers loads a set of nodes from a local file or remote URL, while proxy-groups organizes them into selectable, latency-tested, or failover policies. Rules usually point to a proxy group rather than a specific node.
proxy-providers:
provider-main:
type: http
url: 'https://subscription.example.com/clash'
path: ./providers/provider-main.yaml
interval: 3600
health-check:
enable: true
url: 'https://www.gstatic.com/generate_204'
interval: 600
proxy-groups:
- name: 'Proxy Selection'
type: select
proxies:
- 'Auto Select'
- DIRECT
use:
- provider-main
- name: 'Auto Select'
type: url-test
use:
- provider-main
url: 'https://www.gstatic.com/generate_204'
interval: 300
tolerance: 80
- name: 'Failover'
type: fallback
use:
- provider-main
url: 'https://www.gstatic.com/generate_204'
interval: 300
Common proxy-group types
select: manually choose a node or another proxy group. This is suitable for the destination referenced by rules.url-test: periodically requests a test URL and selects the lowest-latency candidate. The example checks every 300 seconds;tolerance: 80helps prevent frequent switching when latency is similar.fallback: selects candidates by availability and switches to the next usable node when the current connection path fails.load-balance: distributes connections across multiple nodes according to a policy. It does not directly combine the bandwidth of a single download.
proxies explicitly lists node or proxy-group names, while use references providers. Proxy groups can be nested—for example, “Proxy Selection” can include “Auto Select,” which then draws nodes from a provider. When checking a config, follow references level by level and verify that every name exists; avoid creating a group that references itself.
rules: the ordered traffic-splitting table
rules is one of the most important lists near the end of a config. Clash matches from top to bottom and normally stops after the first match. Put specific domain, process, or subnet rules first, followed by broader GeoIP, GeoSite, and catch-all rules.
rules:
- DOMAIN-SUFFIX,example.org,Proxy Selection
- DOMAIN,api.example.net,Auto Select
- DOMAIN-KEYWORD,stream,Proxy Selection
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
- GEOSITE,CN,DIRECT
- GEOIP,CN,DIRECT,no-resolve
- MATCH,Proxy Selection
Rules consist of a matcher, value, and target
In DOMAIN-SUFFIX,example.org,Proxy Selection, the first part is the rule type, the second is the value to match, and the third is the policy used after a match. The policy name must exactly match a name in proxy-groups; built-in targets such as DIRECT and REJECT are also valid.
DOMAINexactly matches one fully qualified domain name.DOMAIN-SUFFIXmatches a specified domain and its subdomains, making it useful for site-wide traffic splitting.DOMAIN-KEYWORDmatches keywords in domain names. Because its scope is broad, avoid overly short keywords.IP-CIDRandIP-CIDR6match IPv4 and IPv6 address ranges respectively.GEOIPuses a geographic IP database to determine the region associated with a destination address.GEOSITErelies on a domain-category database; available categories depend on the current mihomo version and data files.MATCHcatches traffic not matched earlier and should be placed at the end of the rule list.
no-resolve prevents an IP rule from triggering an extra DNS lookup solely for matching. It is often used with LAN subnets or GEOIP rules, but whether to add it depends on the DNS mode and rule requirements above. Adding it to a domain rule has no effect.
Typical symptoms of incorrect rule order
- Putting
MATCHin the middle means rules below it never run. - Writing a broad
DOMAIN-KEYWORDrule first prevents later exact-domain rules from matching. - If a LAN subnet is not sent DIRECT early enough, traffic to routers, NAS devices, or development servers may be routed through the proxy.
- The target name was changed, but the rule table still references the old proxy group, so loading reports a missing proxy or policy.
- Using
GEOSITEorGEOIPwithout the corresponding database can cause rule loading or matching failures.
TUN and profile: common trailing settings
TUN mode takes over more system traffic through a virtual network interface, useful for apps that cannot read system proxy settings. It does not conflict with mixed-port: TUN works at the network layer, while mixed-port remains available to apps that support HTTP or SOCKS5.
tun:
enable: true
stack: mixed
dns-hijack:
- any:53
auto-route: true
auto-detect-interface: true
strict-route: false
profile:
store-selected: true
store-fake-ip: true
auto-route lets the core configure routes automatically, while auto-detect-interface identifies the current outbound network interface. TUN driver, administrator-permission, and routing requirements vary by operating system. GUI clients commonly generate and manage these settings under “Settings” → “Network” or “Settings” → “TUN Mode.” If the client already manages TUN, do not declare the same fields repeatedly across multiple override layers.
store-selected: true saves the proxy-group selection so the previously selected item is restored after restart. store-fake-ip: true saves Fake-IP mappings, helping reduce connection interruptions caused by changed mappings after restart. Both fields belong to profile, not to dns.
A complete check order, from loading to matching
Passing YAML syntax validation does not guarantee that a node can connect; a reachable node does not guarantee that DNS and rules work as intended. Troubleshoot in a fixed order instead of changing several sections at once to isolate problems more reliably.
- Check YAML parsing. Start on the client’s config page or in the core log and confirm there are no indentation errors, duplicate keys, unknown fields, or type mismatches.
- Check local listeners. Confirm that enabled ports such as 7890, 7891, 7893, 9090, and 1053 are not occupied by another process.
- Check the node handshake. Select one node on the proxy page and run a latency test, then review logs for TLS, authentication, timeout, or unreachable-network errors.
- Check proxy-group references. Confirm that rule targets, group members, and provider names match exactly.
- Check DNS. Watch for DNS query timeouts and verify that the DoH server hostname can be initially resolved through
default-nameserver. - Check rule matches. Open the connections or logs page to see which rule matched the destination domain and which proxy group and node were ultimately selected.
- Enable TUN last. Confirm that the regular system proxy works first, then enable TUN to distinguish node issues from routing takeover issues.
A practical route for reading a config
When reading an unfamiliar config, start with the top-level ports, then inspect dns, proxies or proxy-providers, proxy-groups, and rules, followed by tun and profile. This mirrors traffic processing: an application enters through a local port or TUN, DNS resolves the domain, rules choose a proxy group, and the group selects a node.
Maintainability depends less on the number of fields than on clear references. Node names, provider names, proxy-group names, and rule targets form one continuous chain. Whenever a name changes, follow the chain and check every later reference. After editing, reload the config with the client’s validation tool and confirm the actual match through connection logs.