01 · YAML structure and configuration entry points
Clash configuration files typically use YAML. They are not scripts executed line by line, but hierarchical data: top-level keys describe core behavior, nested mappings hold settings for individual features, and lists contain multiple nodes, proxy groups, or rules. When reading a file, first find the fields aligned with the left margin, then look below them for their contents. Do not assume two lines belong together simply because they are close to each other.
Mappings, lists, and indentation
Mappings use a colon to separate keys from values, usually followed by a space. List items begin with a hyphen. Use spaces for indentation; do not mix in tabs. This guide uses two-space indentation throughout. It is a maintainable convention, not part of any field name. Keep items at the same level aligned, especially when distinguishing a second node in a list from additional settings for the first node.
mixed-port: 7890
mode: rule
allow-lan: false
proxy-groups:
- name: PROXY
type: select
proxies:
- DIRECT
rules:
- DOMAIN-SUFFIX,example.com,DIRECT
- MATCH,PROXY
Here, proxy-groups is a list whose first item contains a name, a type, and an optional outbound. Its proxies field is another list. The top-level proxies key defines proxy nodes, while a field with the same name inside a group specifies which outbounds to reference. Its meaning depends on its location. Moving a group reference to the top level may still leave the text parseable, but can cause a type or reference error.
Strings, booleans, and duplicate keys
Ports are usually integers, and switches are usually written as true or false. Passwords, domains, and node names are treated as strings. Add quotes around values containing a hash, a colon followed by a space, or other potentially ambiguous text. A hash in the right context starts a comment, so an unquoted password may be truncated. Double quotes interpret escape sequences; for ordinary text, single quotes can reduce confusion caused by backslashes.
Do not define the same key more than once in a mapping. For example, a dns block at the beginning of a file and another at the end do not necessarily combine. A parser may reject duplicate keys or keep only one value. To add a nested field, edit the existing block. Lists can be written on separate lines or in square brackets, but separate lines make relationships easier to follow when troubleshooting.
Source files and runtime files
Desktop clients often keep the original subscription, an editable copy, override rules, and the runtime configuration passed to the core. Saving successfully in an editor only confirms that the file was written. Whether the change takes effect also depends on whether the client uses that file and whether a later generation step overwrites it. When troubleshooting, first identify the currently active configuration, then inspect the runtime config or core logs. This avoids repeatedly editing an inactive copy.
When running mihomo from the command line, test a configuration with mihomo -t -f ./config.yaml. Adjust the executable name and path in the command to match your installation. A successful test mainly indicates that the structure and some references are acceptable; it does not mean a remote server is reachable or every rule behaves as intended. A client's built-in test and the terminal command may also use different cores, so verify which configuration is actually loaded.
Keep a recoverable baseline: save the original file, limit each change to one feature block, and record why you made it. If an error occurs, undo the latest change before adding fields again one at a time. Avoid changing DNS, TUN, and rule order simultaneously; a failed connection could then have several possible causes. If you only need to complete your first import, follow the subscription import steps first, then return to expand the configuration.
02 · Ports, modes, and general fields
General fields control how the core accepts connections, which interfaces it exposes, and how it selects outbounds. They belong at the top level; their meaning normally does not change depending on whether they appear near the beginning or end of the file. When starting out, keep the listening scope as small as possible and allow only local applications to use the proxy. Once the connection works, consider LAN access, a control interface, or other access methods. The more features you enable, the more boundaries you will need to check when troubleshooting.
Proxy ports and listening addresses
port provides an HTTP proxy endpoint, socks-port provides a SOCKS endpoint, and mixed-port accepts both types of proxy request on the same port. For ordinary desktop use, start with one mixed port. The port number is not fixed; it must match an available local port and the proxy address configured in your application. Changing it will not automatically redirect an old address to the new port.
mixed-port: 7890
allow-lan: false
bind-address: 127.0.0.1
mode: rule
log-level: info
ipv6: false
The example is for local use. When entering a proxy manually in an application, use 127.0.0.1 as the address and the corresponding port number. If the address is already in use, check whether a second client or another core process is running before deciding to close the conflicting program or change the port. Repeated restarts usually will not free an occupied port and can make it harder to tell multiple background processes apart.
Read allow-lan and bind-address together. The former controls whether LAN access is allowed, while the latter controls the listening address. The operating system's firewall also matters. Enabling LAN access alone does not guarantee that other devices can connect. If you need to share access, configure suitable authentication and access boundaries so the proxy endpoint is not exposed to public networks when it should only be available on a trusted network.
Rule, global, and direct modes
mode: rule selects outbounds according to the rule list. Global mode uses the globally selected outbound, while direct mode does not select a remote proxy through ordinary proxy rules. Global mode does not mean that all device traffic is intercepted; it affects only connections that have entered the core. Applications without a system proxy, their own proxy settings, or TUN interception may not pass through the core at all.
| Field | Primary purpose | What to check |
|---|---|---|
mixed-port | Local HTTP and SOCKS endpoint | Application port matches; listening succeeded |
mode | Choose how outbounds are selected | Whether the interface overrides the config value |
log-level | Adjust log detail | Restore the usual level after debugging |
external-controller | Provide a management API | Listening scope and access authentication |
A mode button in the client may change the runtime state through the control interface, while the source file's mode value remains unchanged. If the interface still shows global mode after you edit the file, check whether the client restored your previous selection or has a separate setting that takes precedence. Before changing the entire rule list because no rule seems to match, confirm that rule mode is actually running.
Logs, control interfaces, and persistent state
log-level is commonly set to info; temporarily switch to debug when you need more detail. Detailed logs may contain visited domains, node names, and local addresses. Remove sensitive information before sharing them. A control interface and a proxy port serve different purposes: the former manages the core, while the latter forwards application connections. Do not enter the management port in a browser's HTTP proxy settings or widen the control interface's listening scope to troubleshoot a failed connection.
If you need a control interface, restrict it to the loopback address where possible and set a strong secret. Keep real credentials on your own device. Some clients generate and manage these fields themselves, and a manual override may prevent the interface from connecting to the core. When an option concerns both client preferences and core configuration, use the setting provided by the client first, then verify the result in the runtime config.
Persistent selections can also affect what you see. For example, enabling saved proxy selections may restore a previously selected node after a reload rather than choosing the first item in the group. To confirm that a change took effect, check the runtime mode, the group's current selection, and the connection records—not just the first name in the file. For port conflicts and leftover system proxy settings, see the Help Center.
03 · DNS, Fake-IP, and resolution paths
DNS settings determine how domains are converted to addresses and whether the core can retain domain information for rule matching. Separate three questions: where the application sends its queries, which upstream the core uses to resolve them, and who resolves the proxy server's domain when connecting to a remote node. These paths can differ, so a browser resolving a website address does not mean the proxy server's domain has also resolved successfully.
Basic fields and upstream roles
dns.enable enables the built-in DNS service, while listen sets its listening address and port. A successful listener does not mean the operating system has started using it; the client or system network settings must still send queries to that endpoint. This guide uses a non-privileged port on the loopback address to distinguish it from existing system DNS services. Choose a port based on the actual interception method and permission requirements.
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:
- 223.5.5.5
nameserver:
- https://dns.alidns.com/dns-query
proxy-server-nameserver:
- 223.5.5.5
fake-ip-filter:
- '*.lan'
- '*.local'
nameserver specifies regular DNS upstreams and can contain standard DNS servers or supported encrypted DNS addresses. If an encrypted upstream uses a domain name, the core first needs to resolve its address; default-nameserver can handle this bootstrap lookup. Do not configure the bootstrap resolver to depend on the same unestablished connection needed to reach it, or you may create a loop between getting a proxy connection and resolving the server.
proxy-server-nameserver resolves proxy server domains, allowing node address lookups to be handled separately from ordinary website queries. The resolver must still be reachable from the current network. If logs show that a node's server domain cannot be resolved, first check the node domain and the upstream configured here. Do not add entries to a website-domain filter list; the resolution target is different, so the setting to change is different too.
Fake-IP and real address resolution
Fake-IP mode assigns reserved addresses to domains and stores the mapping between each domain and its address in the core. When an application connects to that address, the core can recover the domain and apply rules to choose an outbound. The reserved address is not the remote website's actual public address. Seeing it does not mean the website's DNS has been changed incorrectly. Understanding this helps avoid mistaking normal mapping behavior for a resolution problem.
By contrast, redir-host more closely resembles returning the actual resolved address to the application. Whether domain information remains fully associated also depends on how the connection enters the core and on other identification mechanisms. Neither mode is universally better. Some LAN services, apps that discover devices using real addresses, or specialized network checks may require real address responses. Adjust the relevant setting for those cases instead of changing every upstream.
Filtering, routing, and troubleshooting
Add filter entries to address confirmed issues. The LAN suffixes in the example are common starting points, not a guarantee that they suit every network. If your router uses internal domain names, queries must reach a local resolver that can answer them. Adding an internal domain to the filter will not make a public DNS server recognize its records. When troubleshooting, check both the filter result and the upstream actually in use.
To route specific domains to different upstreams, look into nameserver-policy. To make DNS connections follow routing rules, evaluate respect-rules alongside the node domain resolution settings. These options change the path of DNS traffic, not just the query result. Map out the dependencies before enabling them, especially to ensure that the resolution required to establish a proxy connection does not depend on that not-yet-established connection.
When testing DNS, distinguish among “no response,” “an address is returned but the connection fails,” and “only one application fails.” For the first, check the listener, interception, and upstream reachability. For the second, check rules, outbounds, and IPv6. For the third, check the application's cache, built-in encrypted DNS, or another path that bypasses system DNS. After changing the mapping mode, old connections and cached results may persist; create a new test connection before checking the result.
Do not confuse top-level ipv6 with dns.ipv6. They concern the core's overall IPv6 behavior and IPv6 DNS responses, respectively. Disabling one does not mean all system IPv6 traffic is handled appropriately. For more on reserved address mapping and filter boundaries, read Fake-IP Mode Explained, then choose settings for your network.
04 · Proxy node fields and providers
A proxy node definition describes how the core connects to a remote service. It differs from a proxy group: the node stores protocol, server, and authentication parameters, while the group organizes and selects outbounds. A node can pass a syntax test and still fail to connect because of invalid credentials, an unreachable server, or incorrect transport settings. Test a single node first, then add it to a more complex group to keep selection logic from obscuring the results.
Names, protocols, and server parameters
Common shared fields include name, type, server, and port. Use a unique, recognizable name for references from groups and rules. The protocol type must match the server. The server can be an address or a domain, and the port must be the one the remote service actually listens on. The local mixed proxy port and remote node port are on opposite ends of the connection; they do not need to match.
proxies:
- name: SS-DEMO
type: ss
server: proxy.example.com
port: 443
cipher: aes-128-gcm
password: 'your-password'
udp: true
This shows the shape of the fields. The domain and password are instructional examples and cannot be used to connect to a remote server. Use actual parameters from a server you are authorized to access. Do not infer that a proxy port is available just because a website opens, or add TLS simply because a port is commonly used for HTTPS. The encryption method, password, and protocol type must match as a set; an error in any one of them can look like a timeout or handshake failure.
Supported fields depend on the core actually in use, not just the client name. Different builds of the same client may include different core capabilities, and protocols in an old configuration may not be compatible with newer examples. If you encounter an unknown protocol or field, check the running core and its documentation before changing the configuration. For differences among core branches, see mihomo vs. the Original: Feature Differences.
TLS, transport, and UDP
For protocols that use TLS, the server address, certificate verification name, and transport-layer host field may have different roles. servername usually specifies the name used in the TLS handshake, while the WebSocket path and request headers belong to the transport layer. Do not replace every domain in a subscription with the same value, or delete a field just because it appears redundant. Check each one against the server's actual configuration.
Do not treat skipped certificate verification as a general fix. For certificate errors, first check the device time, server name, certificate validity, and whether you connected to the wrong port. Disabling verification changes the security boundary and may temporarily hide a wrong server or mismatched configuration. Consider this setting only when you understand the specific test environment and its risks; normal configurations should retain appropriate verification.
udp: true allows the node to handle the relevant UDP requests; it does not guarantee that the server, protocol implementation, and entire network path support UDP. Ordinary browser requests through an HTTP proxy are not a substitute for UDP testing. If voice calls, games, or some DNS requests fail, check how the application enters the core, whether the node supports the required transport, and whether the server firewall allows it. Do not rely only on whether the switch is enabled.
Proxy providers and health checks
proxy-providers lets you separate the node list from the main configuration. A file provider reads a local file, while an HTTP provider fetches content from a specified address; proxy groups in the main configuration reference them with use. This allows node updates without changing the whole set of rules. Provider files have their own structure requirements, however; a complete subscription containing modes, rules, and DNS settings is not automatically a valid provider file.
proxy-providers:
local-nodes:
type: file
path: ./providers/local-nodes.yaml
proxy-groups:
- name: PROXY
type: select
use:
- local-nodes
This example requires a real local file containing a proxies list and valid nodes. Relative paths are resolved from the core's working directory, which may not be the directory of the file open in your editor. If the logs say the file cannot be found, first check the client's working directory and access permissions, then adjust the path. There is no need to copy every node manually into the main configuration and obscure the original path issue.
A health check needs a test address reached through the selected outbound. It measures that path to the test target, not the entire internet. Failures can be caused by the target, DNS, timeouts, or the node. Subscription URLs often contain access credentials, too. Never paste a complete URL into a public log or screenshot. Before sharing a configuration, retain its structure but replace passwords, subscription parameters, and other identifying details.
05 · Proxy groups, references, and selection state
A proxy group organizes multiple outbounds under a name that rules can reference. After a rule sends a connection to a group, the group chooses the actual node based on its current selection or test logic. A group named PROXY is not inherently guaranteed to use a remote proxy, and a custom group named DIRECT should not be confused with the built-in direct outbound. Judge behavior by the references in the configuration, not by a name's literal meaning.
Manual selection and complete references
select is a manual selection group, suitable when the user should make the choice. The group's proxies list can include existing nodes, other groups, and supported built-in outbounds; use references providers. Names must match exactly, including spaces, capitalization, and punctuation. When renaming a node, check every place that references it. Otherwise, the file may be syntactically valid while the core cannot find the target.
proxy-groups:
- name: PROXY
type: select
proxies:
- DIRECT
- name: MEDIA
type: select
proxies:
- PROXY
- DIRECT
rules:
- DOMAIN-SUFFIX,example.com,MEDIA
- MATCH,PROXY
This snippet uses only direct routing and references between groups to demonstrate the structure; it contains no real proxy nodes. A visit to the example domain first enters MEDIA. If MEDIA selects PROXY, the connection then uses the outbound currently selected in PROXY. Groups can be nested, but avoid circular references. For example, if group A references B and B references A, the outbound decision chain breaks; this is not a way to create two-way failover.
Automatic testing and failover
url-test selects an outbound based on test results and is often used for automatic selection. fallback focuses on finding an available candidate in order, while load-balance distributes connections according to a supported strategy. These are not interchangeable forms. For predictable priority, a failover group is often easier to understand than one that constantly chases test results. To pin a business group's outbound manually, add a selection group at the outer level.
Automatic groups typically need a test address, check interval, and other parameters. Choose an address for your network and confirm that its responses are stable. A test result describes the path to that target, not the speed of every service. Some nodes may perform well against the test site but be unsuitable for long-lived connections, streaming, or other destinations. Consider actual service performance alongside automatic test results.
A shorter check interval is not always better. Frequent checks increase requests and wake device radios, which matters especially on mobile devices with background restrictions. Some check mechanisms support on-demand testing, so a group that has not been used for a long time may not keep its results current. If a test status looks old, first confirm whether the group has actually been checked recently before treating a cached observation as a current result.
Persistent selection and service groups
You can create groups for media, development tools, or other types of traffic, then have different rules reference them. This separates “which requests belong to this category” from “which outbound this category uses.” You can change nodes without rewriting every domain rule. Avoid splitting groups too finely: users would have to maintain too many selections, and troubleshooting a connection would require following multiple layers of references.
profile:
store-selected: true
When selections are saved, a restart or reload may restore the previous state. Changing node order does not necessarily change the current selection, while renaming a group may leave saved state without a matching group. When testing a new default order, check persistent state and whether the client stores selections separately. Moving a node to the top does not guarantee that every installed client will use it next time.
If a group looks wrong, check its name, reference source, candidate list, and current selection in that order. A provider that has not loaded may leave the candidate list incomplete, while an overly strict filter may remove all nodes. For an empty group, check provider update logs and filter expressions first. Changing the rule target to another group would only work around the problem, not fix its source.
Also distinguish between “the current selection exists” and “the current selection can connect.” A manual group can retain a failed node, and an automatic group may be unable to connect if all candidates are unavailable. Once the group structure is verified, return to the single-node connection logs and check the server, protocol, and DNS. For differences among client interfaces, consult the Client Comparison Guide to choose a configuration management approach.
06 · Rule syntax, order, and rule providers
In rule mode, connections are checked against the rule list from top to bottom. Typically, the first matching rule determines the target outbound. Rules do not combine all matches into a vote, and a more specific rule later in the list does not automatically override an earlier one. When reading a configuration, start with the order, then check whether each expression is correct. Putting a broad catch-all condition at the top makes most rules below it ineffective.
Domains, addresses, and the final catch-all
DOMAIN matches a specific domain, DOMAIN-SUFFIX matches a domain and its subdomains, and DOMAIN-KEYWORD matches based on a keyword. Suffix rules are generally easier to control than broad keyword matches. Domain rules match the hostname, not the full URL. Do not include a protocol prefix, path, or query parameters in the domain field; copying a valid URL may still result in no match.
rules:
- DOMAIN,router.example.com,DIRECT
- DOMAIN-SUFFIX,example.com,PROXY
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
- MATCH,PROXY
The exact-domain direct rule comes before the suffix proxy rule, so it can act as an exception. Add LAN address ranges based on your actual network. This example does not cover every address range and is not a substitute for a complete network boundary design. MATCH has no match content and catches remaining connections; the field after it is the outbound name. If that name does not exist, the catch-all cannot make a valid decision either.
When an address rule is applied to a domain target, resolution may be needed for the match. no-resolve avoids triggering a domain lookup specifically for that address rule. It does not disable all DNS or guarantee that the connection was never resolved. A connection whose target is already an address can still be matched by address. When debugging, use the logs to see which domain and target address the core received.
Process rules and how traffic enters the core
Some environments support matching by process name or path, but the ability to obtain process information depends on the operating system, permissions, and connection method. A connection from another device on the LAN generally cannot be associated with its remote application process in the same way as a local connection. If a rule does not match, first confirm that process identification is available, then check the name. Do not keep adding synonymous process rules to compensate for missing metadata.
Rules also cannot handle connections that never enter the core. If a program ignores the system proxy, even an exact process rule may never get a chance to match. First check whether the connection appears in the records. If it does not, check the application's proxy settings or the TUN interception path. If it appears but reaches the wrong group, check the current mode, rule order, and domain information. This separates traffic entry issues from rule expression issues.
Rule providers and matching formats
rule-providers stores rules in a separate file or remote resource, which the main list references through RULE-SET. behavior describes the content semantics, such as domains, address ranges, or classic rules; format describes the file format. Both must match the resource. A regular webpage, a complete configuration, and a rule list are not interchangeable based only on their file extensions.
rule-providers:
local-domains:
type: file
behavior: domain
format: yaml
path: ./rules/local-domains.yaml
rules:
- RULE-SET,local-domains,DIRECT
- MATCH,PROXY
A domain rule file can use the structure below. The provider definition in the main configuration and the file contents together determine whether it loads correctly. Checking only the main file can miss a format mismatch. File paths are also resolved relative to the core's working directory. On first use, confirm that the resource exists, is readable, and has loaded before testing a domain match.
payload:
- '+.example.com'
- 'router.example.net'
Subscription updates and rule-set updates are separate processes. A successful node refresh does not mean that rule resources refreshed successfully; an old cache may still be in use. If routing fails for only one category of websites, check the relevant provider's load logs, then trace a specific domain's match result. Do not widen keyword rules repeatedly instead of troubleshooting the resource; that can introduce subtle false matches.
For final verification, use a new connection. Existing long-lived connections may keep their original outbound, and browser connection reuse can make a rule change appear ineffective. Choose a specific test domain, close its old connections, visit it again, and check the matched rule, proxy group, and final node. For guidance on reading log fields, see How to Troubleshoot Runtime Logs.
07 · TUN, routing, and interception boundaries
TUN uses a virtual network interface to send traffic that meets routing conditions into the core. It is useful for applications that do not follow system proxy settings. TUN and rule mode work at different layers: TUN controls how traffic enters, while rules determine where it goes afterward. Enabling TUN does not mean every request must use a remote proxy; rules can still send LAN or specified traffic through DIRECT, or reject particular connections.
Basic structure and permissions
Desktop systems typically require administrator permissions, service mode, or appropriate network privileges. Mobile systems use the platform's VPN interface for interception. Whether a client provides a graphical switch or installs a service automatically varies by platform. If activation fails, first check logs related to the virtual interface and permissions. Do not assume that traffic has entered TUN just because the interface switch appears to be on.
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
This is a common combination of fields, not a universal configuration for every device. auto-route sets relevant routes automatically, while auto-detect-interface helps select an outbound interface. On systems with multiple network adapters, remote desktops, containers, or other tunnels, automatic selection may still be unexpected. Keep a recovery method before changing routes, especially if you are testing an unverified interception setup over your only remote connection.
Network stacks, DNS hijacking, and actual behavior
Depending on core support, stack can use implementations such as system, gvisor, or mixed. They differ in system compatibility, processing, and resource use. mixed uses a hybrid approach; it is not a label meaning “newer and faster.” Start with the value recommended by your client, then adjust it for a confirmed compatibility issue. Avoid changing the stack, routing, and DNS mode at the same time, or you will lose a clear basis for comparison.
dns-hijack redirects matching traditional DNS requests to the core's DNS handler. The port match in the example does not mean it can identify and redirect every form of encrypted DNS. Queries sent by an application over HTTPS share an entry point with ordinary web traffic and cannot simply be handled as traditional DNS on a standard DNS port. A browser's built-in resolution mechanism may also change domain visibility, so identify the application's resolution path when testing.
Built-in DNS must still work after TUN is enabled. If DNS queries are intercepted but no upstream is available, applications may appear to wait indefinitely for resolution. If queries bypass the expected path, some domain rules may lack the information they need. A useful troubleshooting order is virtual interface, routes, DNS, nodes, and rules. Do not just keep switching between Fake-IP and real address modes.
| Environment | Check first | Common boundary |
|---|---|---|
| Windows desktop | Service permissions, virtual interface, other VPNs | System proxy settings and route interception are different layers |
| macOS desktop | Authorization status, network service order | Recheck after sleep or a network change |
| Linux desktop or server | Network permissions, policy routing, firewall | Container namespaces may differ from the host |
| Mobile device | VPN authorization, other VPNs, background limits | Platform capabilities differ from desktop implementations |
LAN access, other tunnels, and troubleshooting
LAN access depends on both routing and traffic selection. A DIRECT rule for a private network range determines the outbound for connections that have entered the core; it does not necessarily resolve every system routing conflict. If a printer, shared folder, or internal admin page stops working after TUN is enabled, compare routes, target addresses, and connection records before and after. Then consider appropriate route exclusions rather than allowing all traffic through.
When TUN runs alongside a corporate VPN or another network tunnel, the default route, DNS, and interface priorities may conflict. The clearest baseline test is to keep only one interception tool active, then verify resolution and destination access separately. Once each works on its own, investigate route separation. Do not exclude or intercept every network interface; extreme changes can prevent the core from establishing its own outbound connection.
If the network still behaves unexpectedly after exiting TUN, check that the client properly removed its interface, routes, and system proxy settings, then confirm that no other network tools are still running. First restore the relevant client settings and exit normally. Do not delete unfamiliar system routes directly. For more on setup, permissions, and network stacks, see the TUN Mode Setup Guide.
08 · Overrides, merging, and configuration validation
Subscriptions often need regular updates, while local ports, DNS settings, and personal routing rules should remain in place. Overrides store these differences outside the source configuration, then let the client generate a runtime configuration. This is not a standardized YAML feature: merge order, list handling, and scripting capabilities vary among clients. Understanding the final result matters more than memorizing the name of a button in a particular interface.
Distinguish replacement, recursive merging, and appending
Overriding an individual scalar field is usually straightforward; for example, changing mixed-port. A mapping may be recursively merged or replaced entirely. Lists are more likely to differ: a client may replace the original list, append to the end, or insert entries at the beginning through a dedicated option. Do not assume that two files containing rules will automatically preserve every rule from both.
# Override snippet: exact merge behavior depends on the client
mixed-port: 7890
dns:
enable: true
enhanced-mode: fake-ip
profile:
store-selected: true
If the client replaces the entire dns block, the example may remove upstreams from the subscription. With recursive merging, nested fields not shown here may be retained. You cannot tell which result applies from this snippet alone. After saving, open the runtime configuration to check that upstreams, listening settings, and filter lists are intact, then test resolution. If the merge behavior is unclear, verify it first with a recoverable test copy.
Rule position and subscription updates
Personal exception rules usually need to appear before broader rules, especially before the final catch-all. If the client only appends new rules after an existing MATCH, the rules will be present in the file but will almost never get a chance to match. That is why “prepend rules,” “append rules,” and “replace rules” in a configuration interface are not interchangeable. Choose the option that gives rules the intended priority.
Direct edits to a subscription's source file may be overwritten during the next update. A safer approach is to manage node sources, business rules, and local environment settings separately, using override or configuration composition features explicitly supported by the client. If the client lacks the feature you need, save a manual configuration and accept the maintenance cost. Do not rely on automatic updates while assuming manual changes will always be preserved.
Changes to node and proxy group names are another update risk. If a personal rule references a group from a subscription and the group is renamed in a later update, the rule will fail even if it has not changed. Where possible, use stable business groups that you maintain yourself, then have them reference updateable node sources. After an update, check that all custom targets still exist instead of relying only on the client's “subscription updated” notification.
Close the validation loop with the runtime configuration
Full validation has four layers: the file parses, references resolve, external resources load, and connection behavior matches expectations. Configuration tests can help with the first two layers. For the third, check provider and node logs; for the fourth, make actual requests and inspect connection records. Passing one layer does not replace the others. In particular, a successful test command does not prove that server credentials are valid or that a rule selects the intended outbound.
mihomo -t -f ./config.yaml
Where possible, test a client-generated runtime file with the core actually used by that client. A separately installed command-line tool may support different fields, making local test results inconsistent with the interface. Runtime files can also contain automatically generated controller addresses, interface names, or cache paths. Do not copy them wholesale to another device. Bring over the configuration logic you need, then regenerate it for the new environment.
| Symptom | Check first | Next step |
|---|---|---|
| Error on startup | Indentation, field types, reference names | Undo the latest change and test again |
| No change after saving | Active configuration, override order, runtime file | Reload and verify the actual fields |
| Rules fail after an update | Rule position, whether the target group was renamed | Fix the reference and create a new test connection |
| Only some requests fail | Matched rule, DNS, final node | Trace the same target through each layer |
Change records and safe sharing
For each change, record three things: why you made it, which layer you changed, and how you confirmed it worked. Keeping a recoverable previous configuration is more useful than saving many unexplained copies. If a problem occurs, return to the latest working state and reapply changes one at a time. If you are both upgrading the client and adjusting rules, test them separately so core differences are not confused with configuration errors.
When asking for help, provide the error time, a simplified relevant snippet, the actual runtime mode, and steps to reproduce the issue. Replace subscription credentials, passwords, and management secrets. Check public screenshots for node remarks, internal addresses, and access records as well. To review installation, import, and connection steps, return to the Getting Started Guide. To identify common error types, visit the Help Center; there is no need to rewrite the entire configuration for every issue.