YAML Structure Overview
A configuration file is structured text, not a list of settings thrown together. YAML uses indentation to show nesting, colons to separate keys from values, and hyphens to mark list items. When reading an unfamiliar config, start with the top-level keys at the far left, then check the indented content beneath each one. This helps distinguish global settings from node-specific fields and prevents valid options from ending up in the wrong place.
Read Objects and Lists Through Indentation
Use two spaces for indentation throughout, and avoid tabs. Keys at the same level should line up; child fields should be indented one level further than their parent. A space usually follows each colon and list-item hyphen. Turn on “show whitespace” in your editor to make indentation visible. When an error points to a line, check the preceding lines too: a missing quote or incorrect indentation may not become apparent until later.
# Loadable by mihomo cores that support these fields
mixed-port: 7890
allow-lan: false
mode: rule
log-level: info
proxies: []
proxy-groups:
- name: Manual
type: select
proxies:
- DIRECT
rules:
- MATCH,Manual
This example demonstrates nesting only: all connections ultimately go DIRECT, and it includes no usable remote proxy. The top-level proxy-groups key is a list, and each item in that list is a proxy group object. Within each object, proxies is another list containing the names of candidate exits. The top-level proxies key, meanwhile, defines proxy nodes. Although the two fields share a name, they appear at different levels and serve different purposes.
Think of the config as a chain of references: proxy nodes define connections, proxy groups refer to node names, and rules refer to group names. DIRECT is a built-in direct connection and doesn't need a same-named entry in the proxy list. References must match exactly, including capitalization, spaces, and punctuation. If you rename “Manual” to “Daily,” update the rule targets too. The syntax may still parse, but the core will report a missing target when it loads the config.
Strings, Booleans, and Empty Values
Quote values that contain special characters, especially passwords, names with a hash, and strings that look like dates. In certain positions, a hash starts a comment; without quotes, it can truncate the value. Use true and false for Boolean values, and numbers for ports. Don't turn everything into a string just to make the file look consistent. [] means an empty list; it isn't the same as a key with no value. Preserve sensitive fields exactly—don't trim spaces inside them.
Don't declare the same key more than once in an object. Two top-level rules keys don't mean the rule lists will be combined. Different parsers may reject the file or keep only one list. If someone sends you a snippet, first determine whether it's a complete file or content intended to go under a parent key; then choose where to paste it. If you only have child entries for nameserver, don't put them at the far left of the file.
Before editing, make a copy of the original file and give the copy a name that explains its purpose. Practice indentation with the minimal example above before reviewing a real subscription; don't use a practice file to replace your production config. Load the config after adding each section—it’s easier than hunting for an error in hundreds of pasted lines. To walk through a complete file section by section, see How to Read config.yaml. The sections below explain individual fields and their limitations.
Ports and Operating Modes
General settings determine where the client receives traffic and how it handles it. Keep the local entry point separate from the remote exit: local ports accept connections from browsers or system proxy settings, while remote node ports connect to servers. The two can happen to use the same number, but that doesn't link them. Rules can only evaluate requests that reach a local entry point, so a correct config doesn't automatically route traffic from every app.
Choose an Entry Point and Control Its Listening Scope
port provides an HTTP proxy, socks-port provides a SOCKS proxy, and mixed-port accepts both types of proxy connection on the same port. A single mixed port is usually enough for common desktop use; there's no need to enable every port just to make the config look complete. The example numbers are local choices. If another program is using a port, choose a free one and update the system proxy and app settings to match.
mixed-port: 7890
allow-lan: false
bind-address: "127.0.0.1"
mode: rule
log-level: info
ipv6: false
allow-lan: false is suitable for local-only use; bind-address specifies the listening address. The loopback address 127.0.0.1 points only to the current device. Even if you enable LAN access, check the listening address, firewall, and client overrides. Don't expose a proxy entry point directly to the public internet. If other devices on your LAN need access, first restrict who can connect, then check which authentication options the core supports.
| Field | What It Controls | Where to Check |
|---|---|---|
mixed-port | Local HTTP and SOCKS access | System and app proxy addresses |
allow-lan | Whether other devices can connect | Listening address and firewall |
mode | Route traffic by rules, globally, or directly | Current client mode |
log-level | Log verbosity | Core runtime logs |
Rule Mode Doesn't Enable the Connection
mode: rule routes traffic according to the rules list; global typically sends proxied traffic to the global selection group; direct handles it as a direct connection. Switching to global mode can help determine whether a rule affects a request, but it isn't a fix-all. It won't help if the app isn't using the proxy entry point or the node itself can't connect.
System proxy and TUN mode work at different levels. A system proxy registers a proxy address with the OS, and apps can choose whether to use it. TUN creates a virtual network interface and routes matching packets to the core. TUN often involves administrator permissions, routing, and DNS interception, and its settings vary by platform. When troubleshooting, start with the system proxy and one known request. Then enable TUN by following the user guide so you don't have to troubleshoot two entry points at once.
Ports and modes shown in the client may take precedence over the config file. If the file says rule mode but the interface shows global mode, inspect the active configuration instead of repeatedly editing the source file. Some clients treat ports as app-level settings that don't change when a subscription reloads. Confirm which port is actually listening, then check the address used by your browser or command. This helps prevent requests from going through a different proxy that's also running.
Use info for routine logging and switch to debug temporarily when troubleshooting. Verbose logs generate more output and may include destination domains, addresses, and connection paths, so check for sensitive information before sharing them. Return to your usual log level when you're done to avoid accumulating unnecessary records. The controller manages the core; it isn't an internet access point. Don't enter its port as the system proxy, or widen its listening scope just to make it easier to manage.
Check IPv6 last. The top-level ipv6 setting and the option with the same name in the DNS section affect connection and resolution behavior separately; the exact effect depends on the core. It's disabled in the example to narrow the scope of initial troubleshooting, not because every network should keep it off. If your network and proxy exit support IPv6, test it separately once the basic connection works. Check the AAAA results and actual outbound address to confirm that more than just the interface toggle changed.
DNS and Domain Resolution
DNS translates domain names into network addresses. Even if your rules use domain names, DNS may still be needed to connect to the proxy server, reach the destination site, or determine which region an address belongs to. When troubleshooting, ask: “What is resolving the name, where is it sending the query, and what result did it get?” Don't assume every timeout means the node is down. A browser's built-in encrypted DNS can also bypass the system's normal resolution path, making apps on the same device behave differently.
Standard DNS and Fake IP
enhanced-mode selects the enhanced DNS mode. With fake-ip, the app receives a mapped address, which the core uses to look up the original domain; it's not the site's real address. This makes it easier to retain domain information for rule matching, but the request must later pass through the same core. redir-host mainly returns the actual resolved address and behaves more like traditional DNS. Don't switch back and forth based on a recommendation for one website without first understanding how traffic enters the core.
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"
- "localhost"
default-nameserver:
- 223.5.5.5
- 119.29.29.29
nameserver:
- https://dns.alidns.com/dns-query
This config creates a local DNS listening endpoint, but listen alone doesn't change the system DNS settings or enable TUN interception. If the system still sends queries to the router, the core's settings may not be handling them. To verify the DNS path, check the client's DNS interception settings, system network settings, and logs together. If the listener uses a nonstandard port, typical system DNS settings can't specify that port directly; use a compatible app or interception mechanism.
default-nameserver is commonly used to resolve the hostnames of encrypted DNS services. The example uses IP addresses to avoid a loop where a resolver's hostname must be resolved before the resolver can be reached. nameserver specifies regular upstream DNS servers; the example uses HTTPS, commonly known as DoH. Encrypted DNS still requires network access, may not connect directly in every environment, and isn't a substitute for a proxy node. Before changing upstream servers, check that they're reachable from your current network.
Choose a Resolver by Domain
Some domains need a specific resolution path—for example, company intranet domains that exist only on internal DNS. mihomo supports selecting an upstream resolver by domain with nameserver-policy. The internal domain and resolver address below are examples only; replace them with values provided by your network. Add this to the same dns object, not to a second top-level DNS key.
# Merge into the existing dns object
nameserver-policy:
"+.corp.example.com":
- 192.168.1.1
The Fake IP filter list keeps specified domains from using virtual address mapping; it isn't the same as a direct-connection rule list. After adding a domain to the filter, its traffic is still subject to routing rules. If LAN discovery, a game, or an app that relies on real addresses has a confirmed issue, test the filter for the affected domain. Don't add every domain: that would disable the mechanism you intended to use.
In supported mihomo configs, proxy-server-nameserver can specify the resolver for proxy server hostnames. This is separate from resolving website domains; it helps find the proxy server before connecting to it. If you use options such as respect-rules that make DNS connections follow routing rules, check for loops: the resolver may require a proxy, while the proxy server needs the resolver to find its address. Unless you have a specific need, keep the resolution path simple.
Check DNS in two steps: first confirm that the query reaches the core, then confirm that the result can be used for the connection. In Fake IP mode, a mapped address may be expected; don't treat it as the remote server's address. If only one app is affected, check its built-in DNS, cache, and proxy setup first. If all apps fail at once, investigate upstream reachability and DNS interception. Change one DNS option at a time so you can tell which step made a difference.
Proxy Node Fields
A proxy node describes the parameters needed for a remote connection; a name alone won't make it work. The protocol determines which fields are required, the server determines their values, and the client core determines what's supported. If your subscription already provides nodes, preserve their original settings and adjust only the proxy groups or rules. Manually changing the cipher, transport, or authentication details rarely makes a connection faster and often makes the client settings incompatible with the server.
Check the Common Fields First
name is the local name referenced by proxy groups; type identifies the protocol; server is the remote server's domain or IP address; and port is the server's listening port. You can name nodes by purpose, but keep names unique and avoid conflicts with group names or built-in exits. For a hostname, enter only the host—don't include https:// or a page path. Don't copy the local mixed port; use the port specified by the server provider.
proxies:
- name: Example Exit
type: ss
server: proxy.example.com
port: 443
cipher: aes-128-gcm
password: "your-password"
udp: true
proxy-groups:
- name: Manual
type: select
proxies:
- Example Exit
- DIRECT
This example uses a reserved example domain and a fake password to show the structure of a Shadowsocks node; it doesn't provide a working proxy. To connect, you need a legitimately obtained server address, port, cipher, and password. cipher must match the server; don't treat it as a security level you can choose at random. When copying a password, watch for spaces inside quotes, special characters, and line breaks. Text that looks the same in the interface may not contain the same characters.
| Field Category | Typical Values | Common Causes of Errors |
|---|---|---|
| Addressing | server、port | DNS resolution, connection timeout, or refused port |
| Authentication | password、uuid | Handshake failure or server rejection |
| Transport | network and protocol options | Mismatched path or transport |
| TLS | servername and related fields | Certificate name, trust chain, or system clock |
Don't Mix and Match Protocol Parameters
Authentication fields vary between protocols. Some use a password; others use a UUID. The transport may be TCP, WebSocket, or something else. Don't combine fields from multiple guides and expect the core to figure out which ones you intended. Confirm the protocol, then check its field definitions for your current core. A field supported by another client may not use the same syntax here. Unknown fields may be ignored, so you won't always get a clear error.
TLS encrypts the connection and verifies the identity of the other end. servername often specifies the server name used during the handshake; it isn't the node's display name. If a certificate error occurs, check the server details, device clock, and whether the names match. Don't disable certificate verification as a permanent fix—it can hide an incorrect address or a trust issue. The WebSocket request path and headers must also match the server configuration; don't infer them from the website's homepage URL.
udp: true enables use of the node's UDP capability; it can't add UDP support to a server that doesn't have it. If browsing works but games or voice calls don't, check whether the local entry point accepts UDP, whether the protocol and server support it, and whether the rules send those requests to the intended exit. An HTTP connectivity test alone doesn't verify the full UDP path, which is a common reason a node appears available while an app still fails.
For a larger node pool, proxy-providers can manage the collection, and proxy groups can reference it with use. A proxy provider isn't the same as a subscription that returns a complete config file: it expects a compatible node-list format, so you can't paste in any subscription URL. Remote URLs may also contain access credentials; remove them before sharing a config. If you're new to this, use your client's existing subscription manager and add a provider only when you need a separately managed node pool.
When switching clients, keep a copy of your config and check which core and protocols the new client supports. You can start by choosing Clash Plus on the download page; choose other clients based on your device. If node details came from a provider, compare them with the original information when a connection fails instead of renaming every node. Clear names help when reading logs, but don't improve connection performance. Reliable field references matter more than elaborate naming.
Proxy Groups and Selection
A proxy group sits between traffic and its connection choices. Rules can send a request to a group instead of a specific remote node, and the group then determines the exit. When you change nodes, you usually need to update only the group selection—not rewrite every rule. To understand a group, check its candidate members, how it selects them, and which rules refer to it. A group name alone doesn't tell you where traffic will go.
Manual Selection, Automatic Testing, and Failover
select provides manual selection for cases where you want direct control over the exit. url-test selects based on connectivity tests to a specified URL, but the result only reflects that target and test method—not every app's experience. fallback checks candidates in order to find an available one, which suits a clearly defined primary-and-backup setup. Each type solves a different problem; “automatic” doesn't mean one group type is right for every use case.
proxy-groups:
- name: Auto Candidates
type: url-test
proxies:
- Example Exit
url: https://www.gstatic.com/generate_204
interval: 300
tolerance: 50
- name: Daily Exit
type: select
proxies:
- Auto Candidates
- Example Exit
- DIRECT
This snippet requires “Example Exit” to be defined under proxies; it can't be loaded as a complete config on its own. The test interval is in seconds; tolerance is a tolerance in milliseconds that helps prevent frequent switches due to small fluctuations. Choose a stable, reachable test URL that works for your network—the example isn't mandatory. If the test target itself is blocked, failure across the group doesn't prove that every node will fail for other destinations.
When “Daily Exit” selects “Auto Candidates,” requests are passed to the inner group to select a node. Selecting “Example Exit” uses that node directly; selecting DIRECT connects without a proxy. DIRECT in a group is a selectable exit, not just a note about a backup. If a type of traffic must use a proxy, don't accidentally leave a selectable direct route in its path. At minimum, know which member is currently selected.
References and Reliability
Groups can reference other groups, but they must not form a loop. For example, if “Daily Exit” includes “Media Exit” and “Media Exit” includes “Daily Exit,” there's no path that can complete the selection. Plan a simple one-way chain: a group for a specific purpose points to a selection group, which points to a node or built-in exit. Give each extra layer a reason; excessive nesting just to make the interface look organized makes troubleshooting harder because you have to inspect each level.
Automatic switching mainly affects new connections; it doesn't guarantee that existing ones move immediately. A website may reuse connections, and a video may keep a long-lived connection, so traffic can continue using the old exit after a switch. For sign-ins, payments, or services sensitive to your exit address, a stable selection may be preferable to chasing test results. To verify a switch, close old connections and make a new request, then check the full proxy chain in the connection details—not just whether the group button changed color.
load-balance distributes connections among candidates according to its configured strategy; it doesn't add together the bandwidth of a single download connection. Different connections may use different exits, which can cause a site to ask you to verify your identity again. If you don't have a clear load-balancing need, start with manual selection or a simpler automatic group. Complex groups require core support and an understanding of candidate availability, connection persistence, and whether your apps need a consistent exit.
When using a provider to supply nodes, a proxy group can reference the provider name with use; don't treat the provider as a regular node name. Filters determine which candidates are available, and a faulty regular expression can leave the group empty. If nodes disappear after a subscription update, check in order whether the provider updated successfully, whether the filter matches, and whether the node names changed. Don't start by deleting rules: rules route requests to a group, but they don't create its members.
Clients may save manual selections, so reloading a config doesn't necessarily reset the group to its first option. When troubleshooting, note the current selection, explicitly choose another if needed, and make a new request. Keep group names stable, especially when rules, override files, or saved client selections refer to them. If you need to restructure groups, preserve the existing names and verify the new candidates before gradually updating references. This is easier to roll back than renaming everything at once.
Rule Syntax and Order
Rules are usually checked from top to bottom, and the first match determines how traffic is handled. The core doesn't automatically choose the “most specific” rule. Rules must be both correct and in the right position. Think of them as a series of junctions: once a request is routed at an earlier junction, it won't reach the rules below. A common source of confusion is a broad rule near the top catching traffic before a more specific rule farther down.
Domains, Addresses, and the Final Catch-All
Most rules use the format “type, match, target,” such as DOMAIN-SUFFIX,example.com,Daily Exit. The value in a domain rule is a domain, not a URL—don't include a scheme, port, or path. DOMAIN matches an exact domain; DOMAIN-SUFFIX matches the domain and its subdomains; DOMAIN-KEYWORD matches a keyword in the domain string. Keyword matching can be broader than expected, so prefer an exact domain or suffix when you know the domain.
rules:
- DOMAIN,router.lan,DIRECT
- DOMAIN-SUFFIX,example.com,Daily Exit
- DOMAIN,ads.example.net,REJECT
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
- GEOIP,CN,DIRECT
- MATCH,Daily Exit
This requires an existing “Daily Exit” proxy group. IP-CIDR matches an IP address range; GEOIP uses an IP database to determine the region; MATCH needs no match value and acts as the final catch-all. If you put MATCH near the top, the rules below it won't get a chance to match. The private network example includes only two ranges, not every local address. Your network may need additional ranges, IPv6 rules, or internal domain rules.
| Rule Type | What It Matches | Notes |
|---|---|---|
DOMAIN | Exact domain | Doesn't include other subdomains |
DOMAIN-SUFFIX | Domain and its subdomains | Don't include a URL path |
IP-CIDR | Destination IP range | Use the correct rule type for IPv4 or IPv6 |
GEOIP | IP geolocation database | Results depend on the database and DNS resolution |
MATCH | All remaining requests | Usually placed last |
DNS Resolution and Rule Providers
no-resolve is commonly used after address-based rules that support it. It prevents the rule from triggering a DNS lookup solely for the purpose of matching. It doesn't mean the connection will never need DNS. If the request already includes a real address, the rule may still match; if it has only a domain and no address is available, it may not. Adding this option to every address rule changes which rules can match, so consider it alongside the domain rules above and the final catch-all.
GEOIP,CN checks the region in an IP database; it doesn't identify the language of a website or where its domain was registered. A site using a content delivery network may return addresses in different regions, and databases may lag behind updates. If a particular service needs a consistent exit, consider a domain-specific rule instead of relying entirely on region matching. Before updating Clash GeoIP data, check the format and path used by your core, then use the update option provided by your client.
For larger rule sets, rule-providers can manage them separately and RULE-SET can reference them. The provider's behavior type must match its content format—for example, a domain list and a classical rule list aren't interchangeable. Remote rule updates also depend on download paths and network access; the rules aren't always available as local text. Start by testing a few local rules. Once their order is correct, add a rule set to help distinguish content issues from update issues.
Process rules can match a program name or path, but support depends on the operating system, core permissions, and how traffic enters the core. If process information isn't available, adding more process rules may not help. Don't assume a program-identification rule can be copied between mobile and desktop systems. To check whether an app's traffic reaches the core, first see whether its process appears in the connection record; then decide whether to use this type of rule.
To verify a rule, record four things: the destination domain, the matched rule, the proxy group, and the final exit. A site may also request resources from separate domains for images, sign-in, and APIs, so matching its main domain may not cover the whole page. If a page loads but images fail, inspect the actual failed requests instead of broadening the rule to unrelated keywords. For common matching issues, see the Troubleshooting FAQ. Narrow down the cause before changing the rules list.
Overrides and Configuration Merging
An override keeps the original config and changes its effective result through another layer; merging combines multiple sources into the config the core actually reads. Neither is a universal feature of the YAML format, and clients can implement them differently. YAML describes objects and lists, but operations such as inserting at the top of a list, preserving nodes, or processing a script are usually handled by the client. Before using someone else's override snippet, check which client and processing stage it targets. Don't assume every app handles it the same way.
The Source Config Isn't the Effective Config
A subscription config may pass through several stages: download, client-level setting overrides, user overrides, and script processing before it reaches the core. Check the client documentation for the actual order. If the interface and file don't match after an edit, look for an option such as “View runtime config” or “Export effective config.” Reopening only the downloaded source file may never show ports, DNS settings, or rules added by the client later.
Editing a downloaded subscription file directly is risky: the next update may download fresh content and overwrite your local changes. A safer approach is to use subscriptions for remote nodes and overrides for personal rules and local settings, maintaining them separately. If the client doesn't support the overrides you need, you can make a local copy—but it won't automatically receive future subscription changes. Choose based on whether you need ongoing updates, not on which option takes fewer clicks.
# Original snippet
dns:
enable: true
enhanced-mode: fake-ip
nameserver:
- 223.5.5.5
# Expected result: preserve other keys and replace only the upstream list
# This shows the result; it is not a universal override directive
dns:
enable: true
enhanced-mode: fake-ip
nameserver:
- 119.29.29.29
The key idea above is to “preserve the other keys in the object.” With a shallow replacement, submitting a new dns object containing only nameserver may remove the original enable and enhanced mode settings. A recursive merge may keep them. Don't infer the result just because a snippet looks reasonable. After applying it, expand the effective DNS object and confirm that all required, unchanged fields are still there.
Replacing Lists and Choosing Where to Insert
Lists need particular care. rules, proxies, and the candidates inside a proxy group are all lists. A merge tool may replace a list entirely, append to it, or match its items by name. Replacing the rules list can remove the subscription's existing routing rules; simply appending your custom rules might put them after the existing MATCH, where they'll never match. What you usually need isn't just to “add” a rule, but to place it precisely while preserving the catch-all.
For example, to send docs.example.com directly, insert DOMAIN,docs.example.com,DIRECT before any broad rule that could match first. The name of the insertion option varies by client. Don't put tool-specific directives such as “prepend” directly in the core's rules list. When you're done, inspect the top and bottom of the effective list. Confirm the rule is in the right place, there's only the intended catch-all, and all referenced groups still exist.
Don't override a proxy group list by array position alone. A subscription update may reorder its members, so the second group may no longer serve the same purpose. Overrides that match by name are generally easier to maintain, but you still need to account for upstream group renames. After each update, check that important groups have candidates and personal rules still point to valid targets. If you added a fixed node name as a candidate, update it if the provider removes or renames that node.
Keep three separate copies for local maintenance: the original subscription, your personal override file, and a snapshot of the verified effective config. If something breaks, disable the newest override, restore the last verified version, and add changes back one at a time. Don't change nodes, DNS, and rules in the same round of testing, or you won't know which layer caused the difference. Explain the purpose of each change—for example, “direct connection for internal domains”—rather than recording only a date.
After merging, test a subscription update. Successfully loading the config by hand only proves that the current file works; it doesn't show whether your settings will survive the next remote refresh. When the update finishes, check the relevant rules, DNS settings, and group selections to confirm the override ran at the expected stage. If behavior changes, compare the effective configs first, then check the upstream content. Don't rush to reinstall the client; this step usually reveals which fields were removed or duplicated.
Validation and Troubleshooting
Validate a config at three levels: whether the text parses, whether references load, and whether actual connections behave as expected. Passing a YAML syntax check confirms only that the indentation and basic format are valid. A missing node name or unsupported protocol field can still make the core fail to load it. Even after a successful load, an app may not be using the proxy. Troubleshooting these levels in order is more reliable than changing the whole file after seeing one timeout.
Check Before Loading
After editing, save a copy and use the configuration checker provided by your client. If you have a command-line environment and have installed mihomo, you can use the core's test command. The path in the command is an example filename; run it from the directory containing your actual file. On Windows, use the executable at its installed location. Also account for relative-path resources, rule files, and data directories. Copying only the main file doesn't guarantee that the test environment matches the client.
mihomo -t -f ./config.yaml
For a YAML parse error, check nearby indentation, colons, quotes, and hyphens. If a proxy or group is missing, follow the name reference back to its definition. If a field or protocol isn't supported, check the current core instead of randomly deleting fields. After the test command passes, load the config and check the startup logs to confirm the client is using that file. Otherwise, you may have tested a copy while the active Profile is still pointing to a different file.
Test the Entry Point with a Known Request
Choose a test destination you can access repeatedly, confirm the local port, then make a request that explicitly uses the proxy. The command below assumes a local mixed port is listening on the example port and that curl is installed. It uses an HTTP proxy to access an HTTPS site, which helps confirm that the request reaches the local entry point. A successful command doesn't mean other apps on the system are using the proxy too.
curl --proxy http://127.0.0.1:7890 --head https://example.com
Check the client's connection log at the same time. If no new request appears, check the port, listening address, whether the app is running, and whether the command reached a different proxy. If the request appears, inspect the matched rule and proxy chain. Only after the matched rule, group selection, and exit are as expected should you troubleshoot the node and remote connection. Interpret the response code in context: not every site responds to a HEAD request the same way it does to a regular page request.
| Symptom | Check First | Avoid for Now |
|---|---|---|
| Config won't load | Syntax, supported fields, name references | Repeatedly switching remote nodes |
| No connection records | App entry point, system proxy, TUN routes | Adding lots of routing rules |
| Unexpected rule match | Rule order, destination domain, effective config | Deleting the entire DNS object |
| Rule matches but connection times out | Group selection, DNS, remote handshake | Treating global mode as a permanent fix |
“Connection refused,” “DNS resolution failed,” “handshake failed,” and “timeout” in the logs point to different stages. A refused connection may mean nothing is listening on the port; for a DNS failure, check the resolution path first; a handshake failure calls for checking the protocol, authentication, and TLS; a timeout requires checking network reachability at the stage where it occurred. Don't share only the last error line—nearby records provide useful context. Before sharing logs, remove subscription URLs, credentials, and any destinations you don't want to disclose.
If a Windows Store app fails while a browser works through the same entry point, see How to configure the UWP loopback exemption. If the client exits on startup, follow the startup crash troubleshooting guide to check logs and roll back the config. Different symptoms need different fixes; don't reinstall at the first sign of trouble. Reinstallation may leave the old config in place or remove useful troubleshooting clues.
After validation, restore any temporary debugging settings, save a working copy of the final config, and record the test destination and scope of your changes. If an issue returns, start by reverting the most recent change. To revisit the setup workflow, return to the user guide; for common symptoms, see the FAQ; to choose a client for your device, visit the download page. The troubleshooting order in this guide remains the same: verify the entry point first, then trace DNS, rules, and the exit.