1. YAML Structure and Configuration Read Order
A Clash configuration file is essentially a data tree made up of keys, values, lists, and mappings. The top level usually contains ports, operating mode, log level, DNS, proxy nodes, proxy groups, and rules. When the core starts, it parses the YAML syntax first, validates field types next, initializes listening ports, the DNS module, and outbound proxies, and then loads the rules. If syntax parsing fails at the start, nodes and rules never become active. During troubleshooting, first confirm that the entire file parses successfully before investigating whether a particular rule matches.
YAML uses indentation to express hierarchy. Two spaces are recommended; do not mix spaces with tabs. A space usually follows each colon, list items begin with a hyphen, and text containing colons, hashes, braces, or unusual spaces is best quoted. An unquoted hash starts a comment, so everything after it is ignored. Boolean values should be written as true or false, and numbers such as ports should not be mistakenly quoted as text. Clients may reorder fields when saving, but as long as hierarchy and types remain unchanged, order generally does not affect the meaning of top-level fields.
Expanding the Minimal Structure
An easy-to-follow configuration can start with five parts: listening port, mode, nodes, proxy groups, and rules. The example below shows relationships only: define nodes under proxies, reference their names from a proxy group, and route traffic to that group from the rules. Referenced names must match exactly, including capitalization, spaces, and symbols. If a rule points to a proxy group that does not exist, the core will usually report the missing target during validation.
mixed-port: 7890
mode: rule
log-level: info
allow-lan: false
proxies:
- name: "example-node"
type: socks5
server: 192.0.2.10
port: 1080
proxy-groups:
- name: "Manual Select"
type: select
proxies:
- example-node
- DIRECT
rules:
- DOMAIN-SUFFIX,example.com,Manual Select
- MATCH,DIRECT
The addresses in the example are for documentation only; real connections require server details supplied by your subscription. When writing a node manually, confirm the protocol and required fields first, then add protocol-specific options. Subscription-generated configurations are often longer because they also include DNS, sniffing, rule providers, and multiple proxy groups. You do not need to read every line from top to bottom: find the top-level keys first, then trace the reference chain from “rule target → proxy group → node”.
Anchors, Aliases, and Duplicate Keys
YAML supports anchors and aliases for reusing parameter sets, but not every visual editor preserves them completely. After subscription conversion, GUI saves, or remote overrides, anchors may be expanded into ordinary fields. If a configuration must move frequently between clients, spelling out the fields directly is usually safer. Duplicate keys are another common issue: when two mode or two dns keys appear at the same mapping level, a parser may use the latter or reject the file outright. Do not rely on overwrite behavior; remove duplicate top-level keys before merging.
UTF-8 is the recommended file encoding. Proxy group and node names may contain non-Latin text, but short English names are easier for external scripts to match. Line-ending format generally does not affect parsing. However, copying a configuration from a web page or chat app can introduce full-width colons, curly quotes, or invisible spaces. When you see an error such as “mapping values are not allowed here”, inspect the reported line and the one above it for indentation, colons, and unclosed quotes before deleting the entire section.
2. Common Fields, Listening Ports, and Operating Modes
Common fields determine how the core receives traffic from the local machine or LAN and how it reports runtime information. The most common entry point is mixed-port, which accepts both HTTP and SOCKS proxy requests on one port, making it convenient for browsers, terminals, and the system proxy. You can also configure port and socks-port separately, but that increases port-management overhead. The “system proxy port” shown in a client usually comes from these fields. After editing the file, confirm that the GUI client has not overridden them with its own settings.
allow-lan controls whether other devices can connect through this device’s proxy port. Set it to false for single-device use. If set to true, also use bind-address to limit the listening scope and check the operating system firewall. Allowing LAN connections does not provide authentication automatically, nor does it make a router forward traffic to the port. If each phone and computer runs its own client, there is no need to enable LAN listening.
| Field | Common Values | Purpose and Notes |
|---|---|---|
mixed-port | An unused port from 1024–65535 | Accepts HTTP and SOCKS connections on the same port; update the system proxy settings at the same time. |
mode | rule、global、direct | Determines whether traffic follows rules, uses a single proxy, or connects directly. |
log-level | info、warning、error、debug | Keep info for normal use; enable debug briefly while troubleshooting, then switch back. |
ipv6 | true or false | Controls whether core modules handle IPv6; system networking and DNS settings also matter. |
external-controller | Loopback address and port | Provides a control interface for a GUI or control panel; do not expose it casually to the public internet. |
Rule, Global, and Direct Modes
rule is the mode used most often in everyday operation. The core evaluates rules from top to bottom; once a rule matches, the connection is handed to its proxy group or outbound and later rules are skipped. global bypasses individual rule evaluation and sends all traffic to the global policy. It is useful for temporarily testing whether a node works, but not for verifying rule correctness. direct connects traffic directly and helps distinguish proxy-path problems from local-network problems. Switching modes changes routing decisions only; it does not fix DNS, certificates, permissions, or a disabled system proxy.
The “Rule”, “Global”, and “Direct” buttons in a GUI client usually change runtime state through the control interface rather than rewriting the original YAML. Which mode is used after a restart depends on whether the client persists runtime state and on the configuration’s mode. When troubleshooting a mode that reverts after restart, check the configuration file, client settings, and subscription-update behavior together. Each subscription update may replace the original file, so edits made directly there are often lost; the client’s override feature is a better option.
The Boundary Between System Proxy and TUN
A listening port only means the core is ready to accept proxy requests; it does not make every application send traffic there. The system proxy is a set of proxy addresses published by the operating system, and only applications that read those settings will use it. TUN mode takes over a broader range of IP traffic through a virtual network interface. Both can use the same rules and proxy groups, but their traffic entry points differ. For differences in interception scope, compatibility, and troubleshooting, read How TUN Mode and the System Proxy Work.
mixed-port: 7890
allow-lan: false
bind-address: "*"
mode: rule
log-level: info
ipv6: false
external-controller: 127.0.0.1:9090
The example limits the control interface to the loopback address, which is suitable for a local GUI client. Even when allow-lan is false, make sure you understand the purpose of every listening address. When ports conflict, close duplicate clients or change the port first, then confirm that the system proxy still points to the new port. Editing YAML without updating the system proxy can leave the core running normally while the browser cannot connect.
3. DNS Configuration and Resolution Paths
DNS is one of the most commonly misunderstood parts of a Clash configuration. When an application accesses a domain, it may resolve it itself or pass the domain to the proxy protocol. The system DNS, browser Secure DNS, Clash DNS module, and remote proxy may all be involved. dns.enable only controls whether the core DNS module is enabled; it does not ensure that every application sends queries to it. With the system proxy, some applications still use their own resolution path. TUN mode usually makes centralized interception easier, but DNS hijacking and system permissions still matter.
nameserver is the list of primary DNS resolvers. default-nameserver resolves the hostnames of the DNS servers themselves, avoiding a circular dependency in which the resolver address must first be resolved. If nameserver contains IP addresses, there are fewer dependencies. If it contains encrypted DNS hostnames, provide directly reachable bootstrap resolvers under default-nameserver. fallback and related filtering fields are useful for more complex split resolution, but should not be layered on mechanically; multiple resolution paths can make results difficult to predict.
redir-host and fake-ip
Common values for enhanced-mode are redir-host and fake-ip. redir-host preserves the real resolution result and is easy to understand, but in transparent-proxy scenarios the core may have difficulty recovering a domain from traffic containing only an IP. fake-ip returns a temporary address from a reserved pool for each domain. The core then maps that address back to the domain and applies domain-based rules. It does not connect the destination to that temporary address; the mapping is used for routing. fake-ip is generally friendlier to rule matching and transparent interception, but some LAN services, device discovery, games, and applications that require real IPs may need entries in the filter list.
dns:
enable: true
listen: 127.0.0.1:1053
ipv6: false
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
default-nameserver:
- 1.1.1.1
- 8.8.8.8
nameserver:
- https://1.1.1.1/dns-query
- https://dns.google/dns-query
fake-ip-filter:
- "*.lan"
- "localhost.ptlogin2.qq.com"
- "+.stun.*.*"
- "+.stun.*.*.*"
The example illustrates field relationships and does not mean every network should use the same resolvers. Corporate, campus, and home networks may rely on local DNS for internal domains. In that case, preserve the LAN resolution path or define a dedicated nameserver-policy for internal domains. Use an agreed reserved range for fake-ip-range and do not overlap it with subnets used by the home LAN, VPN, or containers. If LAN devices, printer discovery, or game login fails, first check whether the domain belongs in fake-ip-filter instead of disabling the entire DNS module.
Choosing Resolvers by Domain
nameserver-policy lets specific domains use designated resolvers. For example, send internal domains to the router, local domains to the LAN DNS, and everything else to the primary nameserver. This answers “who resolves the name”; a DOMAIN-SUFFIX rule answers “where does the connection exit”. They are different stages. Choosing the right resolver does not guarantee that the connection will use the corresponding policy. Conversely, a correct proxy rule cannot repair a DNS result that already contains the wrong address.
dns:
enable: true
enhanced-mode: fake-ip
default-nameserver:
- 1.1.1.1
nameserver:
- https://1.1.1.1/dns-query
nameserver-policy:
"+.home.arpa":
- 192.168.1.1
"+.internal.example":
- 192.168.1.1
When troubleshooting DNS, observe three layers: first confirm where the system or application sends the query; then check whether Clash logs show the domain and rule match; finally verify which policy handles the connection. A browser with independent Secure DNS may bypass system settings. If rules contain only IP-CIDR while connection logs retain domain names, match order may also differ from expectations. Do not change DNS mode, rules, and nodes at the same time. Changing one variable at a time makes the real cause easier to identify.
IPv6 and Resolution Results
dns.ipv6 controls whether the DNS module returns AAAA records, while top-level ipv6 affects the core’s overall IPv6 handling. A connection can succeed only when the device network supports IPv6, the resolver returns IPv6 addresses, and the proxy node can handle them. If the local IPv6 path is unreliable, an application may try an AAAA address first and wait for a timeout, making the proxy appear slow. Decide whether to enable it after checking network conditions rather than treating the switch as a universal answer.
4. Proxy Node Fields and Protocol Parameters
proxies is a list of static nodes. Each item includes at least a name, protocol type, server address, and port; other fields depend on the protocol. Subscriptions generally generate complete nodes. When maintaining one manually, do not guess protocol parameters from its name. The same server may expose multiple protocol endpoints with different authentication, transport, and TLS settings. Passing core validation only means the field structure is acceptable; it does not prove that the remote service is reachable.
name is both the internal reference key and the text shown on the client’s proxy page. Proxy groups must use this exact name when referencing a node. Duplicate names make selection and overrides difficult, so keep them unique during import. server may be a hostname or IP address; a hostname requires DNS resolution. port must be an integer. Fields such as udp, skip-cert-verify, and servername should be used only when required by the protocol and transport. Do not copy an entire set of parameters from one protocol to another.
SOCKS and HTTP Upstream Proxies
SOCKS5 and HTTP nodes are commonly used to connect to an existing upstream proxy. Their fields are relatively simple, making them a useful starting point for understanding node structure. If the upstream requires authentication, provide a username and password; otherwise omit them. UDP support depends on the protocol, core, and upstream service. Addresses in the documentation examples are for format illustration only.
proxies:
- name: "office-socks"
type: socks5
server: 192.0.2.20
port: 1080
username: "example-user"
password: "your-password"
udp: false
- name: "upstream-http"
type: http
server: 192.0.2.30
port: 8080
username: "example-user"
password: "your-password"
tls: false
Sensitive fields such as passwords should not be placed in public repositories or screenshots. When syncing a configuration across devices, use a controlled private channel and ensure that the client does not log complete credentials. If a node cannot connect, verify server and port reachability first, then check authentication and transport parameters. Changing proxy groups or rules immediately would mix a node problem with a routing problem.
TLS, SNI, and Certificate Verification
Protocols that use TLS generally require the correct server name. servername, or an equivalent SNI field, tells the remote side which hostname to use during the handshake and may differ from server. When connecting by IP to a certificate issued for a hostname, omitting the correct SNI can make the handshake fail. skip-cert-verify disables certificate verification and should not be a universal switch for TLS errors. A better approach is to check the system clock, server name, certificate chain, and intermediate network. Use this field when the subscription provider explicitly supplies it, and evaluate it against the actual environment.
Transports such as WebSocket and gRPC may also include a path, host header, or service name. YAML hierarchy must follow the protocol’s required location, such as path and headers under ws-opts. When a field is placed at the wrong level, some parsers ignore unknown keys, allowing the configuration to load while omitting handshake parameters. In that situation, compare the core logs with the protocol documentation instead of checking only whether the client displays the node name.
proxies:
- name: "example-tls-node"
type: trojan
server: edge.example.net
port: 443
password: "your-password"
sni: edge.example.net
udp: true
skip-cert-verify: false
network: ws
ws-opts:
path: /gateway
headers:
Host: edge.example.net
Provider Nodes vs. Static Nodes
Static proxies puts nodes directly in the main configuration for easy single-file reading. proxy-providers loads a node collection from a local file or remote resource, making it suitable for subscription updates and combining multiple sources. Use use when a proxy group references a provider, and proxies when it references static nodes. Both can coexist, but watch for duplicate node names, update intervals, and cache paths. Built-in subscription management usually handles these details, so most users do not need to switch to providers merely to make the configuration look simpler.
In graphical clients for Windows, macOS, Android, iOS, and Linux, node parameters are usually maintained by the subscription. The recommended Clash Plus, along with Clash Verge Rev, FlClash, Clash Nyanpasu, Clash Meta for Android, and ClashX Meta, may display configurations differently, but their underlying references are similar. For a platform and client comparison, see Platform Comparison. Do not infer protocol support from interface labels alone.
5. Proxy Group Types and Composition
Proxy groups sit between rules and nodes. Instead of naming a node directly, a rule can hand traffic to a “Manual Select”, “Auto Select”, or “Application Routing” group, which then chooses the actual outbound. This avoids rewriting rules when the node list changes and enables quick switching in the client. Good proxy-group design is not about quantity; each layer should have a clear role: the top layer handles user choice, the middle layer handles health checks or failover, and the bottom layer contains nodes and DIRECT.
select is the most direct type: it uses the node or child proxy group selected by the user. It does not automatically choose the fastest node. url-test periodically tests candidates against a configured URL and selects a suitable result; the test reflects connectivity to that target, not the experience on every website. fallback prioritizes availability and moves to the next item when the current candidate is unavailable. load-balance distributes connections across multiple nodes according to its policy, which may affect login sessions, consistent egress addresses, and fraud controls. It should not be enabled casually as the default group.
| Group Type | Selection Method | Good For | Main Limitation |
|---|---|---|---|
select | User selection | Main entry point, region selection, temporary switching | Does not automatically assess node quality |
url-test | Selection after periodic testing | Automatic selection among similar nodes | The test target may differ from the actual service |
fallback | Sequential failover when unavailable | Scenarios where connection continuity matters | The egress may change after a switch |
load-balance | Distributing connections across multiple nodes | Advanced scenarios where session effects are understood | Does not guarantee a single egress address |
A Common Two-Level Group Structure
A practical structure uses select for a top-level “Proxy Select” group containing “Auto Select”, several regional groups, and DIRECT. “Auto Select” then uses url-test to reference specific nodes. Point rules to the top-level group: choose a node directly when you need stable manual control, or choose the automatic group when convenience matters. Do not let two proxy groups reference each other, or they will form a cycle. Also avoid pointing every rule to a different node; subscription updates will quickly become expensive to maintain.
proxy-groups:
- name: "Proxy Select"
type: select
proxies:
- Auto Select
- Manual Node
- DIRECT
- name: "Auto Select"
type: url-test
proxies:
- node-a
- node-b
url: "https://www.gstatic.com/generate_204"
interval: 300
tolerance: 50
- name: "Manual Node"
type: select
proxies:
- node-a
- node-b
interval is the testing interval. A value that is too short increases requests and battery use; one that is too long fails to reflect network changes promptly. tolerance reduces frequent switching when results are close. The test URL should be stable, lightweight, and representative of the path you want to verify. Test results shown in the client are only one reference; congestion, the destination’s route, and wireless-network changes all affect real-world access.
Managing Provider Nodes with filter
When nodes come from proxy-providers, use use to reference an entire provider and filter to select nodes by name. Filtering generally uses regular expressions. When region labels vary, the expression must accommodate abbreviations, English names, and symbols. An empty result leaves the proxy group with no candidates, so always validate after editing. Rather than writing an overly broad expression, inspect the actual node names first and add matching branches gradually.
proxy-groups:
- name: "Region Select"
type: select
use:
- primary-subscription
filter: "(?i)Hong Kong|HK|Hong Kong"
- name: "Availability First"
type: fallback
use:
- primary-subscription
url: "https://www.gstatic.com/generate_204"
interval: 600
A proxy group’s name is itself a rule target, so renaming it is a structural change. After changing “Proxy” to “Proxy Select”, search rules, rule-provider targets, and references from other proxy groups as well. A client may remember the previous selection; if an old node disappears or the group changes, the runtime selection may fall back to the first item. When publishing a configuration to multiple devices, make the first item an explainable, usable default rather than whichever node happens to appear first.
Where to Place DIRECT and REJECT
DIRECT means a direct connection and suits LAN resources, trusted local services, or targets that should clearly use the local exit. REJECT denies the connection and can block confirmed domains or addresses. Both can be used directly as rule targets or placed in a select group for temporary user choice. Adding DIRECT to the main group increases flexibility, but it also lets users temporarily bypass a proxy rule. Whether to include it depends on the use case.
6. Rule Syntax, Match Order, and Custom Rules
rules is an ordered list. When a connection arrives, the core generally evaluates entries from the top; the first match takes effect immediately, and later rules are skipped. Therefore, a rule that is syntactically correct but ineffective is often being preceded by a broader rule, not suffering from a syntax error. Put exact domains, specific processes, and LAN addresses first; place broad domain suffixes, IP ranges, and regional rules later; finish with MATCH for remaining traffic.
A basic rule consists of a rule type, match value, and policy target separated by English commas. For example, DOMAIN,api.example.com,Proxy Select matches only the exact domain; DOMAIN-SUFFIX,example.com,Proxy Select covers the root domain and its subdomains; DOMAIN-KEYWORD,example,Proxy Select is broader, so any domain containing the keyword may match and should be used carefully. A rule target may be a proxy group, node, DIRECT, or REJECT.
Domain, IP, and Process Rules
DOMAIN rules are clearest when the core has a domain name available. IP-CIDR matches IPv4 ranges, while IP-CIDR6 matches IPv6 ranges using CIDR prefixes. IP rules may trigger domain resolution; if you want to use an existing destination IP without additional resolution, add no-resolve where supported by the core. GEOIP matches according to the IP’s region and depends on the relevant database. PROCESS-NAME and PROCESS-PATH rely on process information supplied by the operating system and may behave differently across platforms, permissions, and TUN implementations, so they are not ideal as the only cross-platform rule strategy.
rules:
- DOMAIN,api.example.com,Proxy Select
- DOMAIN-SUFFIX,example.org,Proxy Select
- DOMAIN-KEYWORD,streaming,Media Services
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
- IP-CIDR6,fc00::/7,DIRECT,no-resolve
- PROCESS-NAME,example-app.exe,Proxy Select
- GEOIP,CN,DIRECT
- MATCH,Catch-All
The example demonstrates order and format only. Adjust LAN ranges to match the actual network, and use the process name shown by the operating system. MATCH belongs at the end because it catches connections not handled earlier. If MATCH appears in the middle, later rules will never execute. Multiple MATCH entries serve no practical purpose; keep one clear final destination.
How to Insert Custom Rules
When a subscription configuration updates, rules appended directly to the original file are usually overwritten. A safer approach is to use the client’s override, extension script, or rule-prepend feature to insert custom rules before the subscription rules. Prepending is suitable for precise exceptions, such as forcing an internal domain to connect directly. Appending works only when the rule still has a chance to run before the subscription’s final MATCH. If the subscription already ends with MATCH, simply adding rules to the end will not work.
When designing a custom rule, answer three questions first: is the match target a domain or an IP; should it use an existing proxy group or a new one; and which existing rules should it override? For one host, prefer DOMAIN. For every subdomain of a site, use DOMAIN-SUFFIX. Consider DOMAIN-KEYWORD only when the naming pattern is unstable. Broad keywords can catch unrelated domains, especially short terms, brand abbreviations, or common words.
rules:
- DOMAIN,printer.home.arpa,DIRECT
- DOMAIN-SUFFIX,internal.example,DIRECT
- DOMAIN-SUFFIX,docs.example.net,Proxy Select
- RULE-SET,private-network,DIRECT
- RULE-SET,service-list,Proxy Select
- MATCH,Proxy Select
How to Read Rule-Match Logs
Logs usually show the destination domain or IP, matched rule type, selected proxy group, and final node. For troubleshooting, make one repeatable request and locate the corresponding connection by time. If the rule target is correct but the final node is not, check the proxy group’s current selection. If MATCH is hit, verify that the expected rule was loaded, the domain matches exactly, and the rule provider updated successfully. If an IP rule appears without domain information, inspect the DNS and sniffing paths.
Opening one browser page creates multiple connections for the main site, images, scripts, and third-party APIs. Do not judge the routing of the entire page from the first log entry. Test one clearly identified domain instead, or confirm the failed request’s hostname in developer tools. Applications may also cache DNS or keep existing connections alive. After changing rules, create a new connection and restart the application if needed; do not assume old sessions switch policies immediately.
Rule Maintainability
Group rules by purpose and add brief comments, such as LAN, personal exceptions, service routing, public rule sets, and final matching. Explaining why a rule exists is more valuable than repeating what its fields mean. Remove exceptions that are no longer used, or it will be difficult to tell whether they remain necessary. Reference stable proxy group names rather than frequently changing node names so subscription updates do not require corresponding routing changes.
7. Rule Sets, Node Providers, and External Resources
When there are many rules, putting everything under rules makes the main configuration difficult to maintain. rule-providers loads rule collections from local files or remote URLs, while the main rules need only reference them with RULE-SET. This organizes and updates rule content but does not choose the policy target automatically; the same rule set can point to different proxy groups in different configurations. Similarly, proxy-providers manages node sources, which proxy groups reference with use.
Common rule-provider behaviors include domain, ipcidr, and classical. domain suits plain domain rules, ipcidr suits address ranges, and classical can contain fuller rule expressions. behavior must match the file contents. Reading DOMAIN-SUFFIX-style classical rules as plain domain data may cause parsing failures or prevent matches. format describes the file format, such as yaml, text, or mrs; check the core in use for the actual supported formats.
Complete Definition of a Remote Rule Set
rule-providers:
private-network:
type: http
behavior: ipcidr
format: yaml
path: ./ruleset/private-network.yaml
url: "https://rules.example.net/private-network.yaml"
interval: 86400
service-list:
type: http
behavior: classical
format: yaml
path: ./ruleset/service-list.yaml
url: "https://rules.example.net/service-list.yaml"
interval: 86400
rules:
- RULE-SET,private-network,DIRECT
- RULE-SET,service-list,Proxy Select
- MATCH,Proxy Select
type: http means the resource is fetched remotely, path is the local cache location, and interval is the update interval. The first load requires network access. If a remote update fails, the core will generally continue using an existing cache; if the first download fails and no cache exists, the rule content is unavailable. The directory must be writable. Desktop clients may also resolve relative paths against their configuration working directory rather than the directory from which the terminal was opened.
Remote URLs should come from trusted sources that are actively maintained. Rule updates can change traffic paths and may have a broader impact than a single node. Before using a third-party rule set, understand its classification logic, update frequency, and default targets; do not judge its contents by name alone. For corporate domains or personal exceptions, keeping a small set of local prepended rules is often better than waiting for a public list to include them.
Rule-Set File Formats
YAML payload format usually uses payload as the top-level key, followed by rule entries. Entries with classical behavior may include prefixes such as DOMAIN, DOMAIN-SUFFIX, or IP-CIDR. domain behavior generally stores only domain patterns, while ipcidr stores network ranges. Do not mix formats arbitrarily, and do not use a file extension as a substitute for the format declaration.
payload:
- DOMAIN,api.example.com
- DOMAIN-SUFFIX,example.org
- IP-CIDR,203.0.113.0/24,no-resolve
When using RULE-SET in the main configuration, the policy target is written at the reference point, so the rule set itself generally does not include a target such as “Proxy Select”. This allows the same list to be reused across configurations. If the downloaded file already contains complete three-part rules, confirm that the provider behavior and the core’s parsing method match it. For an error such as “incorrect number of rule-entry arguments”, inspect the content format rather than changing the proxy group in the main rules.
Node Providers, Health Checks, and Caching
proxy-providers:
primary-subscription:
type: http
url: "https://subscription.example.net/profile.yaml"
path: ./providers/primary.yaml
interval: 21600
health-check:
enable: true
url: "https://www.gstatic.com/generate_204"
interval: 600
proxy-groups:
- name: "Subscription Nodes"
type: select
use:
- primary-subscription
proxies:
- DIRECT
A provider should return content in the structure required for node providers, which is not necessarily a complete Clash configuration. Using a URL for a full configuration as a node provider may fail because its top-level structure is different. A “subscription” in a GUI client usually means a complete configuration subscription and should not be treated as equivalent to proxy-providers. If the client already updates the complete configuration, follow its built-in workflow instead of adding another provider layer.
Health checks test nodes from a provider so automatic groups can assess availability, but checking too frequently increases resource use. On mobile devices, also consider battery consumption and background restrictions. A failed test does not necessarily mean the node is unusable for every destination; the test URL may be blocked or inaccessible from the current network. Combine test results with real connection logs rather than deleting a node based on one status indicator.
A Layered Approach to Update Failures
External-resource failures fall into four layers: download, write, parse, and reference. At the download layer, check the URL, DNS, and current outbound route. At the write layer, check cache-directory permissions. At the parse layer, verify format, behavior, and file contents. At the reference layer, confirm that RULE-SET or use names match the top-level definitions exactly. Remote rule updates may also use the current proxy, creating a dependency where rules are needed to download rules. Give configuration-resource domains an explicit route or ensure a basic connection is available at first startup.
8. Overrides, Merges, Validation, and Troubleshooting
Subscription configurations need regular updates, while personal settings should persist. That is why overrides and merges exist. Editing subscription-generated YAML directly is straightforward, but updates can replace it. Keeping custom content in a separate override layer lets upstream nodes and public rules be maintained independently from local ports, DNS, and personal rules. Clients differ in both terminology and capability: some offer field overrides, rule prepending, rule appending, scripts, or YAML merges. Before using one, confirm whether it replaces an entire field or recursively merges mappings.
Mappings are well suited to recursive key-based merges; lists are where ambiguity arises. For a mapping such as dns, overriding one child key may preserve the others. For lists such as rules, proxies, and proxy-groups, some tools replace the entire list while others support prepending or appending. Assuming that lists merge automatically can erase all subscription rules; assuming they replace can leave two proxy groups with the same name. Do not override large lists until you understand the client’s semantics.
Safe Override Boundaries
Common ports, log level, LAN access, and a small number of DNS child fields are usually suitable for field overrides. Personal domain exceptions suit rule prepending. When adding a proxy group, handle its definition, node sources, and rule targets together, then validate the complete change. Node authentication parameters should normally remain subscription-managed unless you are explicitly managing static nodes yourself. An override file should be shorter than the main configuration and express only what differs from upstream.
# Local override example; follow the client’s merge syntax
mixed-port: 7890
log-level: info
allow-lan: false
dns:
enable: true
ipv6: false
prepend-rules:
- DOMAIN,printer.home.arpa,DIRECT
- DOMAIN-SUFFIX,internal.example,DIRECT
prepend-rules is not a standard top-level field in the main configuration. Some override tools may use it, but it cannot be copied directly into every client. In practice, use the client’s explicit “prepend rules” feature. The example’s purpose is to distinguish main configuration fields from override instructions: the core reads the former, while the client or conversion tool processes the latter before passing the final YAML to the core.
Post-Merge Checklist
After every change, inspect the final generated configuration rather than only the override fragment. Confirm that there are no duplicate top-level keys, listening ports do not conflict, the DNS hierarchy is complete, node and proxy group names are unique, every reference target exists, proxy groups contain no cycles, and the rules end with one clear MATCH. If you use providers, also check cache paths, behavior types, and reference names. Validate the configuration before starting or hot-reloading.
Indentation, colons, quotes, lists, and field types parse correctly, with no duplicate top-level keys.
Rule targets, proxy-group members, and provider names match exactly, with no circular references.
Ports can be bound, the control-interface scope is clear, the cache directory is writable, and DNS can perform basic resolution.
Logs confirm that rule matches, policy selection, and the final node behave as expected.
Validate the Configuration with the Core
Users who run mihomo directly can use the core’s configuration-test option to check the file before starting the service. Executable names and configuration directories vary by installation method, so replace the example with the actual paths. GUI clients usually validate during configuration import or switching and show the failing line on the log page. If a client message is truncated, open the log page for the complete cause.
# Check config.yaml in the current directory
mihomo -t -f ./config.yaml
# Check after specifying the configuration working directory
mihomo -t -d ./clash-profile -f ./clash-profile/config.yaml
Successful validation confirms only that the configuration structure and known fields meet requirements; it does not prove that remote nodes, rule providers, or DNS services work. After startup, observe provider updates, port listening, and connection logs. If validation flags a line, the actual cause may be on the previous line, such as an unclosed quote or incorrect parent indentation. Inspect several lines above and below the error before narrowing the scope.
A Typical Troubleshooting Order
If the client will not open, first check permissions, port conflicts, configuration syntax, and core files; see Startup Crash and App Termination Fixes. If it starts but every connection fails, check whether the system proxy or TUN is actually enabled, whether ports match, and whether the node works. If only some websites use the wrong route, focus on DNS, rule order, and the proxy group’s current selection. If custom content disappears after a subscription update, the edits were made in the upstream file and should be moved to an override layer.
When a port is occupied, do not keep trying random ports without updating the system proxy. Identify the process using it, stop duplicate cores, or choose one clearly defined new port and update every entry point. When a rule does not match, do not immediately add a broader DOMAIN-KEYWORD; get the actual domain from the logs first. When DNS behaves unexpectedly, do not change nameserver, disable fake-ip, and rewrite rules simultaneously. Change one variable at a time and keep a restorable configuration copy.
A successful hot reload with no behavior change may be caused by old connections, application caches, the client’s runtime selection, or an override that was not reprocessed. Create a new connection and check the modification time and contents of the final configuration file to confirm which file the core actually read. Clients with multiple configurations often have three layers: active configuration, subscription cache, and runtime-generated configuration. Editing the wrong file is common. Confirm the active item on the client’s configuration page, then inspect the load path in the logs.
Build a Reversible Maintenance Workflow
A stable maintenance workflow has four steps: save a known-good configuration; make a small change for one objective; validate before loading; and verify actual behavior through logs. If a change fails, revert to the last working configuration instead of layering more patches onto the broken one. Keep separate notes for personal rules, DNS exceptions, and proxy-group structure, including reasons and dependencies, so later cleanup is easier.
Before and after a subscription update, compare top-level fields, proxy group names, and the structure at the end of the rules rather than every node line by line. Newly added upstream nodes usually do not affect personal rules, but renamed proxy groups, changed provider names, or altered rule targets can break overrides. Periodically remove obsolete exceptions and unused providers to reduce future update conflicts. The goal is not the largest possible configuration, but one where every field has a clear purpose, every reference can be traced, and failures can be reversed quickly.