Mihomo Configuration Guide
This guide follows a learning path: understand the core, choose a client, install it, then configure subscriptions, traffic routing and network capture. If you’re new and just want to get connected, start with the quick-start guide. Return to the relevant section whenever you need an explanation of a setting. Both pages use the same terminology, but this guide adds parameter limits, verification steps and rollback options.
Before making changes, keep a known-good copy of your configuration. Change one variable at a time, and record the resulting logs and connection behavior. Strategy group names in examples must match your actual configuration. Code snippets specify their scope; don’t use a partial example as a complete subscription.
1. Core Concepts and Choosing a Client
The Core, the Interface and the Service
Mihomo is the proxy core that parses configuration, matches rules and establishes outbound connections. Clash Meta is a commonly used historical name for its ecosystem. A client provides the graphical interface, configuration management and system integration. Selecting system proxy settings or a strategy group in the interface ultimately changes the core’s runtime state or related system settings. So, seeing that the client is running confirms only that its process is active—it doesn’t prove the subscription is valid, the proxy endpoint works or every app is using the proxy.
The full traffic path includes the app, an entry point, rules, a strategy group and an outbound connection. An app sends requests to the core through the system proxy or TUN. The core decides whether to apply rules based on the selected mode; a matching rule sends the connection to a direct route, rejects it or passes it to a strategy group, which then selects the actual outbound. Subscriptions typically provide outbound settings and some rules, but a client is not itself a network service. After installing a client, you still need a valid configuration source or a service you manage yourself.
Choose the Right Setup for Your Platform
If you’re choosing a client for the first time, consider Clash Plus, then compare other options based on your platform and workflow. On Windows, alternatives include Clash Verge Rev, FlClash and Clash Nyanpasu. On macOS, compare Clash Verge Rev and FlClash. On Android, consider Clash Meta for Android, FlClash or Surfboard. Surfboard’s configuration format isn’t fully compatible with Mihomo, so don’t assume the same YAML can be imported just because both apps are proxy clients. Find platform-specific options in the download center.
| Platform | What to check first | Download |
|---|---|---|
| Windows | System architecture and service permissions | Windows clients |
| macOS | Apple Silicon or Intel | macOS clients |
| Linux | Package format and desktop environment | Linux clients |
| Android | Processor architecture and VPN permissions | Android clients |
| iOS | Supported configuration formats | Clash Plus on the App Store |
Maintenance Status and Limitations
Clash for Windows and ClashX Meta are no longer maintained. They may be useful for understanding legacy setups or migrating old configurations, but don’t assume you should keep using them just because an older guide does. Linux desktop users can compare Clash Verge Rev and FlClash; server and router users can consider running the Mihomo core directly. That approach requires you to manage the process, configuration directory, listening address and routing yourself, without the system integration a graphical client can handle automatically.
To use Clash Plus on iOS, visit clashplus.io for app information, then install it from the App Store page. Even clients with the same name can have different interfaces and system capabilities across platforms. Focus on what a setting does instead of looking for a button in exactly the same place.
By the end of this section, you should be able to answer three questions: Which client is running? Which core or network component handles connections? Who provides and updates the configuration? When comparing clients, look at subscription compatibility, how rules are applied, log visibility and configuration backups—not just how similar the interfaces look. If a client claims to support a protocol, check that your platform and implementation support the specific parameters used by the subscription. Sharing a protocol name doesn’t guarantee that every extension field is interchangeable.
2. Installation, Permissions and Initial Setup
Check System Architecture and Existing Settings
Check your device’s architecture in system information before choosing an installer. Common Windows devices use x64, though ARM devices are also available. On macOS, distinguish Apple Silicon from Intel; on Linux, check both the architecture and the package format supported by your distribution. Don’t guess compatibility based on file size. An installer opening successfully doesn’t guarantee its bundled core will run on your system. If the app exits immediately after launch, check the architecture and system requirements first, then review the app logs—don’t start by changing the subscription.
If you’ve installed another proxy client, quit it first and check whether your system proxy still points to its old port. Closing a window doesn’t always stop background processes; a tray icon, menu bar app or system service may still be running. For your first test, keep only one client responsible for capturing traffic. This avoids two apps repeatedly changing system proxy settings or competing over the default route with separate TUN devices. Keep a backup of old configurations, but don’t enable them while their status is unclear.
Desktop Permissions: A Safe Order
On Windows, install and launch the app normally, then confirm the basic interface opens. Grant elevated permissions only when prompted to install a service or enable a network feature that requires them. The system proxy usually doesn’t require running the entire app as an administrator all the time; TUN or service mode may rely on a privileged helper. If a port is already in use, find out which process is listening. After changing the port, update the system proxy target too—you can’t just change the YAML and leave the old system entry in place.
On first launch in macOS, check the app’s source and requested permissions against the system prompts. A client may install a helper service; some implementations use a network extension. The exact process depends on the app. A Keychain prompt and network extension approval are separate: the former may save sensitive information, while the latter allows the app to handle network traffic. Read who is requesting access before approving a prompt; don’t assume every prompt must be allowed. See macOS permissions and Keychain explained.
Whether a Linux desktop client can set the system proxy depends on the desktop environment and the app. Command-line programs may not read desktop proxy settings at all. After installation, confirm that the core process is running, the configuration loaded and a local port is listening. Then test with an app known to support proxies. When running the core directly, set appropriate read and write permissions on its configuration directory; don’t make the entire directory writable by everyone for convenience. A mismatch between the service account, working directory and relative paths can make an interactive launch work while a background service fails.
Mobile Devices and a Minimal First Run
When Android first establishes a VPN connection, the system asks for permission. That authorizes the traffic entry point; it doesn’t prove the remote endpoint works. Android usually allows only one standard VPN connection at a time, so a work VPN or another network tool may conflict. Battery-saving policies can also pause the client; adjust them only after confirming they cause disconnections. On iOS, follow the app’s prompts to authorize its VPN configuration, then return to the client and check for configuration errors.
# Local listener example; does not include a proxy outbound
mixed-port: 7890
allow-lan: false
mode: rule
log-level: info
The snippet above illustrates basic settings; it isn’t a complete configuration that provides proxy service. mixed-port accepts HTTP and SOCKS requests. allow-lan: false disables the intent to allow local network access, but check the actual listening address and firewall to confirm what is exposed. Start with local access and leave LAN sharing disabled. Installation is complete when the interface, core and local listener work, and quitting the client restores the previous network state.
3. Importing Subscriptions and Managing Configuration
A Subscription URL Is Not the Configuration Itself
A subscription link is a way to retrieve configuration; the downloaded content is what the core actually parses. The link may return a complete YAML file, a list of proxy endpoints only, or a format for another client. Before importing, confirm that the provider explicitly supports your client and its core. Opening the link in a browser only confirms that you received a response—not that it’s a valid configuration. A login page, balance notice or access restriction page may also be returned as a normal webpage.
Find the client’s configuration or subscription manager, add a remote configuration, give it a name that identifies its source, paste in the URL and download it. Then check the update time, parse result and whether strategy groups were created before setting it as the active configuration. Some clients separate “download succeeded” from “enabled successfully.” Saving a file alone doesn’t mean the core switched to it. Verify the active configuration name against the startup logs so you don’t keep editing a file that isn’t in use.
Separate Configuration Sources and Overrides
The provider usually maintains a remote subscription, and direct edits to its downloaded cache may be overwritten by the next update. To keep personal rules, DNS settings or listener options, use the client’s override, merge or extension mechanism. The name and order of these mechanisms vary by client. First check whether a mechanism replaces an entire field or inserts entries before or after the existing list. For rules, an entry appended after MATCH may never take effect, even though the syntax is valid.
Configuration is easier to troubleshoot when you separate it into three parts: the source layer, your override layer and the runtime configuration. The source layer shows what the subscription downloaded; the override layer shows what you added or replaced locally; the runtime configuration shows what the core actually received. If a setting in the interface differs from the YAML, check the effective configuration or logs—not just the original subscription. Some clients inject fields such as ports and control interfaces at startup, so differences between the runtime configuration and the remote file aren’t necessarily errors.
# Partial example: two common top-level fields
mode: rule
log-level: info
# PROXY referenced by rules must be defined in the full configuration
rules:
- DOMAIN-SUFFIX,example.com,DIRECT
- MATCH,PROXY
Fixing Import and Update Failures
If you get a parse error, note the field name and line number in the error message. YAML uses spaces for indentation; don’t mix tabs into it. List item hyphens, spaces after colons and special characters in strings can also affect parsing. The reported line may only be where the parser detected the problem; the actual cause could be a missing quote or incorrect indentation on the previous line. Check the area around the error a few lines at a time. Reformatting the entire file can erase the clues you need.
If a download fails, determine whether the cause is a DNS lookup failure, connection timeout, certificate error, expired authorization or unexpected response content. The client or core may make the subscription request over a different network path than your browser. Change the User-Agent only when the provider specifically asks you to; randomly changing it isn’t a general fix. For a detailed checklist, see Troubleshoot subscription parsing errors. You can also follow the subscription import steps for your first import.
Keep the most recent working configuration before updating, then check that strategy group references still work afterward. A provider may rename an endpoint, making a previously selected member unavailable. If the client preserves old selections, open the strategy group and choose again. Don’t assume an update is complete just because the refresh succeeded—test a real connection and check which rule matched. For subscriptions that change often, have personal rules refer to stable strategy group names rather than endpoint names that may change.
4. Proxy Modes and Strategy Groups
Separate Traffic Entry from Outbound Decisions
System proxy, TUN and Rule are options at different layers. The first two determine how app traffic enters the core; Rule determines how traffic is routed once it gets there. So it’s possible to switch to Global mode and still have an app bypass the proxy: that app may not use the system proxy, and its traffic may not be captured another way. First look for the request in the connection panel. If it isn’t there at all, check the traffic entry point instead of changing the outbound or rearranging rules.
| Mode | How it works | Best for |
|---|---|---|
| Rule | Evaluate rules from top to bottom | Everyday routing by domain and address |
| Global | Choose an outbound using the global strategy | Temporarily compare outbound and rule behavior |
| Direct | Send connections entering the core directly to an outbound | Compare direct connections or restore access temporarily |
Rule is generally the right mode for everyday use. Global can help as a short-term diagnostic, but it won’t fix an expired subscription, a traffic entry conflict or a DNS issue. Direct doesn’t quit the client; traffic capture and core DNS handling may still be active. To determine whether the proxy setup as a whole is causing a problem, quit the client and restore system settings. Switching to Direct alone won’t rule out TUN routing or DNS handling by the client.
How Strategy Groups Reference Each Other
A strategy group sits between a rule and the actual outbound. select lets you choose a member manually; url-test selects a member based on test results; fallback checks members in order until it finds one that works; and load-balance distributes connections according to its configured strategy. An automatic group’s test results reflect only the test URL and method. They don’t prove that a particular website will work, and one displayed metric shouldn’t be treated as a universal measure of quality.
# Add this group to the proxy-groups list in the full configuration
# Structure example with a direct option only; adds no proxy outbound
proxy-groups:
- name: Manual selection
type: select
proxies:
- DIRECT
rules:
- MATCH,Manual selection
In the example, the rule references the group name, and the group references the built-in DIRECT. In a real subscription, you can add defined outbound names to the member list or reference another strategy group, but avoid circular references. Names generally need to match exactly, including capitalization, spaces and symbols. When renaming a group, update references in both rules and other groups. Changing only the displayed name can leave a dangling reference that prevents the configuration from loading.
Verify the Selection with a Single Request
New connections usually use the newly selected strategy group member, but existing long-lived connections may keep using the old outbound. Browser connection pools, downloads and messaging sessions can all stay open. To verify a change, close the relevant page or task, start a new request and check the matched rule, strategy chain and outbound in the connection panel. If needed, close only connections for that app; you don’t have to clear every connection and interrupt other work.
A client may show both a global strategy group and custom groups from the subscription. In Rule mode, the active outbound is the one referenced by the matched rule—not necessarily the group shown at the top of the interface. If changing the outbound has no effect, follow the strategy chain in the connection record one group at a time rather than assuming the client didn’t save your choice. After switching to a configuration from another source with the same name, check whether its group members have changed.
Before moving on, run one controlled comparison: keep the traffic entry unchanged, test the same website in Rule and Global mode, and record where each connection goes. If Global works but Rule doesn’t, check the matched rule and group selection. If both fail, verify the outbound or DNS first. This is a diagnostic comparison, not a recommendation for a permanent setting; it helps narrow the fault to one part of the traffic path. See the strategy group guide for terminology.
5. Rules and Matching Order
The First Matching Rule Wins
Mihomo evaluates standard rules from top to bottom and uses the target of the first match. Rule priority comes from its position, not its type. An exact domain rule won’t automatically take precedence over a broader rule above it. The final MATCH rule acts as a fallback. Put specific exceptions first, broader categories afterward and the default outbound last. Then verify the actual match in the connection panel.
DOMAIN matches an exact domain; DOMAIN-SUFFIX matches a domain and its subdomains; DOMAIN-KEYWORD matches a keyword, which has a wider scope and is more likely to catch unrelated traffic. IP rules match destination addresses. Process rules depend on platform support and process identification. Don’t add a permanent rule for a single IP just because you know one address for a website: CDNs, address rotation and shared hosting can make the rule too narrow or affect other services.
# Partial rules example; PROXY must be an existing strategy group
rules:
- DOMAIN,router.example.com,DIRECT
- DOMAIN-SUFFIX,example.com,PROXY
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- GEOSITE,category-ads-all,REJECT
- GEOSITE,geolocation-!cn,PROXY
- GEOIP,CN,DIRECT
- MATCH,PROXY
example.com is a reserved example domain used to illustrate the syntax; replace it with a domain relevant to your use case. no-resolve means this IP rule won’t trigger a DNS lookup for a domain; it doesn’t disable all DNS requests. If the connection already has a destination address, it can still match by IP. GEOSITE and GEOIP rely on local data files, and the category name must exist. A successful load confirms that the syntax and data are valid—not that the category exactly fits your needs.
Move from Built-in Categories to Rule Sets
When a hand-written rule list gets long, use rule-providers to separate the rule data from the main configuration. A provider defines the source, storage location, update interval and content format; rules reference it with RULE-SET. The domain, ipcidr and classical formats have different requirements—you can’t make them interchangeable by changing a file extension. Entries in a rule set generally don’t specify an outbound; the referencing rules line does.
# Local rule set example: relative paths start from the core's working directory
rule-providers:
local-domains:
type: file
behavior: domain
format: yaml
path: ./rules/local-domains.yaml
rules:
- RULE-SET,local-domains,DIRECT
- MATCH,PROXY
# Save as rules/local-domains.yaml
payload:
- '+.example.com'
A local file lets you verify the format and matching behavior without also troubleshooting remote downloads. After confirming it works, consider a remote source and check how it’s maintained and what it covers. If a remote rule set fails to update, a cached copy may remain active; without a cache, it may fail to load. A successful main configuration update doesn’t mean the rule set updated too—check their logs separately. Don’t blindly combine overlapping rule sets, or it can be difficult to tell which one determined the outcome.
Use Evidence to Find Routing Problems
Check in this order: confirm the request entered the core, inspect its domain and address, record the matched rule, and verify the selected target group. If the connection shows only an IP, check whether the app resolves the domain itself, DNS bypasses the core or domain sniffing conditions are met. Sniffing may recover domain information, but it can’t identify the original hostname for every protocol. Enabling it isn’t a universal fix for rules that don’t match. Before adding rules, find out what information the core actually has.
Some websites use separate domains for login, assets, APIs and media, so a rule for the home page alone may only fix part of the site. Observe the failed connections during a specific action, then add only the necessary scope. Avoid broad keyword rules that capture unrelated traffic. For rule types and precedence, see Custom Rules and Priority; for combining categories, see GEOSITE and Rule Set Routing.
6. DNS, Fake-IP and TUN
DNS Resolution and Connections Are Related but Separate
DNS translates a domain into an address, while the proxy carries the connection that follows. Their network paths may differ. A browser may use encrypted DNS, the system may have a stale result cached, or an app may use its own resolver. So a website failing to load doesn’t automatically mean the outbound is at fault. First check whether the domain resolved, then whether the connection entered the core, and finally which outbound it used. When comparing networks, keep the client configuration the same; changing both at once makes the cause hard to identify.
Fake-IP assigns a virtual address to a domain and keeps a mapping so the core can associate later traffic with the original domain. It isn’t the website’s real address and can’t be used to determine its geographic location. With redir-host, the resolver returns the real address. This may suit environments that need real-address behavior, but rule matching can depend more on domain mappings and DNS results. Neither mode is universally better; test against your needs for LAN access, games or a corporate intranet.
# Partial DNS example; listen on localhost only
dns:
enable: true
listen: 127.0.0.1:1053
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
fake-ip-filter:
- '*.lan'
- 'localhost'
nameserver:
- https://1.1.1.1/dns-query
The example creates a local DNS listener, but doesn’t make the system send queries to that port automatically. You’ll need to connect it separately through system DNS, TUN hijacking or a client integration feature. The example upstream must also be reachable on your network; an encrypted protocol doesn’t guarantee connectivity. fake-ip-filter excludes specified domains from virtual address responses. Add exceptions only for domains with a confirmed compatibility issue. A broad list can change existing routing behavior and make troubleshooting harder.
TUN Requirements and Limitations
TUN uses a virtual network interface to receive IP traffic, which is useful for apps that ignore the system proxy. Before enabling it, check that the required permissions, driver or helper service are ready, and that no other VPN is still running. auto-route configures the relevant routes; auto-detect-interface attempts to identify the outbound interface. Check the actual results on multi-adapter systems, hotspots and corporate networks. TUN can’t bypass permission requirements, outbound protocol limits or firewalls.
# Partial TUN example; use with platform-specific and DNS settings
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
The standard DNS port matches in dns-hijack can’t capture every encrypted DNS connection created by an app. You may not need to enable both the system proxy and TUN; follow the client’s recommendations to avoid overlapping entry points that make the traffic path hard to explain. After enabling it, test a regular website, the target app and LAN services. If a printer, shared folder or corporate intranet stops working, check whether it needs a route exclusion or domain exception instead of sending all traffic direct.
Identify DNS Leaks and LAN Conflicts
Judge a DNS leak against the expected resolution path: which resolver should handle each query, and are any requests bypassing that path? A test site showing a resolver name is only a clue; by itself, it doesn’t prove that all queries do—or don’t—go through the proxy. Check system DNS settings, client logs, the browser’s secure DNS setting and, if needed, a packet capture to confirm where a specific request goes. Check both IPv4 and IPv6; testing one address family isn’t enough to draw a conclusion.
If your corporate network uses a private DNS server, public resolvers may not be able to resolve internal domains. Set a resolution policy for the internal suffixes and ensure the DNS server is reachable through the correct interface. A loop can occur when DNS requests depend on the proxy, while the proxy server’s hostname depends on that same unavailable DNS path. Provide an independent way to resolve the proxy server. For more on Fake-IP’s limitations, see Fake-IP vs. redir-host.
7. Routine Maintenance and Troubleshooting
Keep a Restorable Configuration Baseline
Once your setup is stable, back up the client settings, personal overrides and rule files. A subscription link isn’t a complete backup: the remote content may change, and local strategy group selections or extra rules may not be included. Separate shareable rules from configurations containing account credentials, and store sensitive files somewhere access-controlled. Record your traffic entry method, DNS mode and any special routes. That’s more useful for restoring your setup than a screenshot alone.
Treat client, core, subscription and rule data updates as separate changes. A client update may change the interface or system integration; a core update may change supported fields; a subscription update mainly changes endpoints and configuration content. Update one at a time and run basic checks so you know what to roll back if something breaks. Don’t update everything at once in the middle of your work and then try to recover based only on “it stopped working after the update”—that doesn’t tell you whether the cause was compatibility or a service change.
Troubleshoot Connectivity in Traffic-Path Order
First identify the scope: all apps, one app or one feature on a particular website? Then check whether your network works when the client is bypassed. If it doesn’t, troubleshoot Wi-Fi, mobile data, captive portals or the system’s network state first. With the client running, confirm that the core started, the active configuration is correct and the expected port is listening. If the request doesn’t appear in the connection list, check the system proxy, app proxy settings or TUN before changing the outbound.
Once the request reaches the core, check the DNS result, matched rule and final outbound. If the same outbound fails for several sites, check the service status, authentication parameters and remote connectivity. If only one site fails, check its rules, dependent domains and protocol differences. An HTTP error means you received an application-level response; it isn’t the same as having no network connection. For certificate errors, check the system time, destination domain and any intermediate device first. Don’t hide the cause by disabling certificate validation.
# Test the local HTTP proxy listener; use the port from your configuration
curl -I --proxy http://127.0.0.1:7890 https://example.com
# Test the SOCKS listener and let the proxy resolve domain names
curl -I --proxy socks5h://127.0.0.1:7890 https://example.com
These commands test only the specified listener and website; they don’t prove that every app is using the proxy. In PowerShell, use curl.exe if a command alias behaves differently. socks5h and a regular SOCKS URL differ in where domain names are resolved. Record which form you used when comparing results. Don’t just check whether both commands succeeded—use the logs to confirm which rules they followed. Otherwise, one might connect directly and the other through the proxy, making the comparison misleading.
Logs, Caches and Restoring Network Settings
For everyday use, keep the log level at something appropriate, such as info. Increase detail temporarily when troubleshooting. Record the time, destination and error from a failed action; that’s more useful than collecting logs indefinitely. Before sharing logs, remove subscription URLs, authentication fields, internal hostnames and request paths that could reveal business information. Detailed logs can also use more resources. Restore the usual log level after finding the cause, and avoid keeping unnecessary connection details.
After changing DNS or the proxy mode, cached results and long-lived connections may make things appear unchanged. Close relevant connections first, then flush system or app caches if needed; there’s no need to delete the entire client directory. If the network still fails after quitting the client, check whether the system proxy points to a closed local port, TUN routes were restored and DNS still points to a reachable address. For a quick check, see System Proxy Settings and Verify a Connection.
Subscription Update Failed. Should I Reinstall the Client?
Check the link, response content and request path first. Reinstalling won’t fix expired authorization or a change to the remote format, and could erase local overrides. Reinstall only if you’ve confirmed that the installation files or client environment are damaged.
The Connection Still Shows the Old Outbound After Switching. What Should I Do?
First confirm you changed the strategy group actually referenced by the matched rule, then close the relevant long-lived connections and try again. Existing connections may continue using the old outbound, so old entries alone don’t mean the change failed.
8. Advanced Configuration and Verification
Modularize First, Then Add Automation
Advanced setup doesn’t mean turning on every feature. It means understanding the inputs, outputs and failure behavior of each part of your configuration. Once you have a stable setup, separate personal rules from the subscription, organize larger rule lists into standalone providers, then consider proxy providers and automated strategies. After splitting out each module, verify its paths, name references and load order. Modularity should narrow the scope of changes—not turn a simple configuration into a maze of references.
proxy-providers and rule-providers solve different problems: the former supplies a set of proxy outbounds; the latter supplies matching conditions. Strategy groups and rules typically reference them, respectively. Don’t assume a complete client subscription can be used as a proxy provider without checking it. Even if it includes proxies, it may also contain other sections required by the client, and its actual parsing behavior needs to be verified. For an unfamiliar remote file, inspect its structure locally before adding it to an automatic update workflow.
Build a Test Matrix for Your Strategy
Test different categories of traffic, not just one familiar website. Include a local gateway, LAN service, site that should connect directly, site that should use the proxy and the app you actually care about. Record the expected entry point, rule and outbound for each. If IPv6 is involved, check which address family is selected; for UDP, confirm that both the traffic entry and remote endpoint support it. A webpage loading proves only that one TCP path works—it doesn’t confirm that voice calls, games or other UDP-based features work too.
| Test case | What to check | Check first if it fails |
|---|---|---|
| LAN service | DNS resolution and direct rules | Internal DNS and route exclusions |
| Site using the proxy | Rule, strategy chain and outbound | Group selection and outbound authentication |
| Standalone app | Whether it appears in the connection panel | App proxy settings and TUN entry |
| UDP traffic | Protocol and error logs | Entry point capability and remote support |
Use repeatable tests, such as reopening the same page, starting the same voice call or accessing a fixed LAN service. Write down the expected result before changing settings so “it feels faster” or “it worked once” doesn’t get mistaken for a correct configuration. For automatic groups, also check what happens when health checks fail, members change or the network switches. Make sure the automation fits your needs rather than just looking normal in the interface.
The Command-Line Core and Control Interface
Before running the core without a graphical interface, understand its working directory and configuration file paths. Relative paths are usually resolved from the working directory, which can affect rule files, caches and data files. Forgetting to copy local provider files when moving a configuration to a server is a common cause of failure. Check the configuration and logs in the foreground before setting up a service. The service account may have different permissions from your interactive login, so verify its access to directories and network features separately.
# Check the configuration in an environment where mihomo is installed
mihomo -t -d ./mihomo-work -f ./mihomo-work/config.yaml
# After validation, run it in the foreground
mihomo -d ./mihomo-work -f ./mihomo-work/config.yaml
Configuration checks can catch syntax errors and some reference issues, but they can’t prove that a subscription URL, DNS upstream or every outbound will be reachable at runtime. After testing in the foreground, use the same parameters in your system’s service configuration. If you enable an external control interface, restrict its listening address and protect access. Don’t expose it to the public internet just to make a remote dashboard convenient. The interface can usually change runtime state, so its risks are different from those of a read-only webpage.
Record Troubleshooting Results as Change History
For each change, record the reason, fields involved, test cases and rollback steps. Keep a minimal working baseline for complex configurations: a clear entry point, few strategy groups and easy-to-follow rule paths. If something breaks, remove new features one at a time and compare with the baseline instead of layering on configuration snippets from unknown sources. For questions about configuration formats, see Subscriptions and Configuration Formats. To review the first-time setup, return to the quick-start guide.
You don’t need to memorize every field to finish this guide. You need to be able to explain a connection from the app’s entry point through DNS resolution, rule matching and strategy selection to its actual outbound. Next, learn only what your use case requires, such as standalone rule sets, choosing a resolver by domain or running the core as a server process. A readable configuration with verifiable behavior and reversible changes is easier to maintain than one with ever more parameters.