Start by separating UI crashes, background processes, and core exits
When searching for “Clash won't open,” first determine whether the window disappeared or the entire process stopped. Clash clients handle the UI, subscription imports, and configuration management, while the Clash or Clash Meta (mihomo) core handles proxy connections, rule matching, and DNS. The UI may appear normally even when the core fails to start; the core may also keep running after the UI window closes. These cases require different logs and recovery steps.
Launch it once, wait about 10 seconds, and check the system tray, Activity Monitor, or Task Manager. Do not keep double-clicking the app: an existing instance, background service, and new launch requests can overlap, making port conflicts and exit timing difficult to interpret.
| Observed behavior | Check first | Evidence to keep |
|---|---|---|
| Window disappears, but the tray menu still opens | Close-to-tray behavior and launch-minimized settings | Tray status and whether the UI process remains active |
| Both the window and UI process exit | Architecture, UI runtime dependencies, and app data | System crash reports and UI logs |
| UI opens but reports a core startup failure | Config parsing, resource paths, and listening ports | The first specific error before the core exits |
| Errors or exits occur only after enabling TUN | Service permissions, virtual adapters, and route conflicts | Log differences before and after enabling TUN |
| UI and core run normally, but websites cannot load | Proxy interception, DNS, nodes, and rules | Connection records; not enough on their own to diagnose a crash |
Back up before making changes: preserve configuration, logs, and version details
A direct uninstall may leave corrupted user data behind or remove subscriptions and overrides that have not been exported. “It still crashes after reinstalling” does not prove that the installer is at fault. First record the client’s full name and version, core version, operating system version, and architecture, and note whether the issue began after updating the client, updating a subscription, or changing configuration. The client version and core version are separate details; “latest version” is not enough.
What to include in the backup
- Original configuration and subscriptions: Save local YAML files, subscription records, and older configurations that still work. Subscription URLs often contain access credentials and should be stored like passwords.
- Overrides and merge logic: Save rule additions, configuration merge fragments, and scripts separately. A valid subscription source does not guarantee a valid generated runtime configuration.
- Client settings: Record system proxy, TUN, service mode, local listening ports, and control interface settings; take screenshots if needed.
- Failure logs: Keep about one minute of records before and after startup, including both core logs and UI process errors.
If the UI opens, use the client’s options for opening the config directory, opening the log directory, or exporting data. Menu names vary between clients. If the client cannot start at all, consult its documentation to locate the data directory. Windows %APPDATA% and %LOCALAPPDATA%, and macOS ~/Library/Application Support/, are only possible parent locations. Do not delete the entire directory or mistake the installation directory for the user data directory.
Exit the client normally before copying anything, and confirm that related processes are no longer writing to files. In service mode, also stop the relevant service through the client’s supported service-management entry point. Do not bulk-end tasks based on a vague process-name match. When sharing logs, create a separate redacted copy covering subscription tokens, node passwords, control-interface keys, private domains, and usernames.
Runtime environment checks: architecture, dependencies, and complete extraction
Choose the package for the device architecture instead of guessing from the filename
On Windows 11, open Settings → System → About and check “System type.” Common Intel or AMD desktop systems generally use x64, while ARM devices should be checked against the project’s ARM64 package availability. On macOS, open Apple menu → About This Mac and check “Chip” or “Processor” to distinguish Apple Silicon from Intel. On Linux, use uname -m; the common outputs x86_64 and aarch64 correspond to x64 and ARM64.
Matching the processor architecture is not enough. The minimum OS version, Linux runtime-library versions, and desktop environment may also matter. If you see Exec format error, check the executable’s architecture first. If the message explicitly says GLIBC_… not found, verify the distribution and the program’s build requirements instead of manually replacing core system libraries. For Android packages, choose an ABI supported by the device; an older device cannot be assumed to run every ARM64 app simply because it has a 64-bit processor.
Dependencies must match the specific client implementation
- Windows WebView UI: If a WebView2-based client reports a missing runtime or initialization failure, repair the corresponding runtime according to the project documentation. Electron clients use a different dependency set, so installing WebView2 is not a universal fix.
- Missing DLLs: Repair the runtime library for the matching architecture only when the error or project documentation specifically points to components such as the Visual C++ runtime. Do not download individual DLLs from unknown sources and place them in the system directory.
- Portable packages: Fully extract the package to a local directory that the current user can read and write, then launch it from the extracted directory. Running directly from an archive preview can leave out the core, resources, or adjacent files.
- System blocking: Check Windows Security → Virus & threat protection → Protection history, or the relevant notice under macOS System Settings → Privacy & Security. Identify the exact blocked file and reason; do not disable the entire system security stack.
On Windows, press Win + R, enter eventvwr.msc, and look under Windows Logs → Application for errors around the startup time. Record the faulting application, faulting module, and exception code. Module details can help distinguish UI rendering problems from core exits, but a module name alone cannot establish the root cause.
Permissions and port checks: narrow the scope by disabling TUN first
If the client only started failing after TUN was enabled or a service was installed, disable TUN in the UI, exit, and launch it once. TUN takes over traffic at the network layer and usually involves system authorization, a service, or a virtual adapter. The system proxy mainly provides a proxy entry point for apps that follow system proxy settings; they are not the same switch. A normal UI launch and listening only on a high local port generally do not require ongoing administrator privileges.
If the client starts after TUN is disabled, check the client service status, system VPN authorization, and conflicts with other VPN or virtual-adapter software. On Windows, repair service mode according to the current client documentation. On Android, handle VPN authorization or another app occupying the VPN slot separately from an app UI crash. Do not delete every virtual adapter or grant all users write access to the entire data directory.
Check for a listening conflict on local port 7890
When the log shows address already in use or Windows reports Only one usage of each socket address, first identify the specific conflicting address and port. The commands below apply only when the configuration actually uses 7890; if the error points to the control interface or DNS port, check the port shown in the log instead.
# Windows PowerShell: find the process listening on 7890
Get-NetTCPConnection -LocalPort 7890 -State Listen |
Select-Object LocalAddress, LocalPort, OwningProcess
# macOS: find the TCP listening process
lsof -nP -iTCP:7890 -sTCP:LISTEN
# Linux: list TCP listeners and process information
ss -ltnp
Use the process identifier in the output to confirm what owns the port; a regular Linux user may not see complete process information for other users. If another proxy client owns it, exit that client normally. If it is a leftover service from the current client, handle it through the relevant management entry point. If you must change the port, update the browser or system proxy entry as well; otherwise the app may keep connecting to the old port even after the core recovers.
Configuration checks: verify the YAML actually read by the core
When the UI opens but the core exits repeatedly, look for the first specific error in the logs instead of focusing only on the final “startup failed” message. Common causes include YAML indentation errors, rules pointing to nonexistent policy groups, unsupported node types, and missing resource files. Clash and mihomo support different field sets; a client being able to import a subscription does not mean the core it invokes can execute every field in it.
Check the merged result before checking the original subscription
- Confirm which configuration file is currently selected, then use the logs or a client function to locate the configuration actually being run.
- Check whether overrides, scripts, rule additions, or proxy collections are enabled; temporarily disable processing steps added most recently.
- Check that YAML uses spaces for indentation, and verify that policy-group names, rule targets, and proxy references match exactly.
- Distinguish a subscription download failure from a configuration parsing failure: a URL that returns a login page or error page is not YAML that the core can parse.
If you use mihomo and can run its standalone executable, start with a configuration test. The commands below assume the current directory contains an executable named mihomo and diagnostic.yaml; on Windows, assume the filename is mihomo.exe. Use the actual filenames bundled with the client, and do not replace the client core merely for testing.
# macOS / Linux
./mihomo -v
./mihomo -t -f ./diagnostic.yaml
# Windows PowerShell
.\mihomo.exe -v
.\mihomo.exe -t -f .\diagnostic.yaml
Use -v to record the core version and -t to test the configuration. When the configuration uses relative paths, proxy collections, or rule collections, follow the core’s help text and use -d to specify the corresponding working directory; otherwise resource locations may cause additional errors. A successful test only means the configuration passed in that test environment. It does not guarantee that ports can bind, TUN has permission, or remote nodes are reachable.
Isolate subscription issues with a minimal direct-connection configuration
The following is a mihomo diagnostic example with no proxy nodes and no proxy exit. Use it only as a separate test file after making a backup, disabling the system proxy and TUN, and confirming that 7890 is unused. Do not overwrite the original subscription file; also temporarily disable any overrides added automatically by the client.
mixed-port: 7890
allow-lan: false
mode: rule
log-level: info
rules:
- MATCH,DIRECT
If the minimal configuration starts but the original does not, restore proxy nodes, policy groups, rules, DNS, and overrides one at a time until you find the first failing change. If the minimal configuration produces the same dependency, permission, or port error, return to the runtime-environment checks. Do not try to fix a UI process crash by switching Fake-IP, changing DNS servers, or altering other network parameters.
Configuration recovery: isolate old data instead of wiping it
Once the runtime environment has been checked, logs point to a failure while reading local settings, or only old user data triggers the issue after an update, isolate the data directory for testing. The goal is to determine whether the failure follows the old data, not to permanently discard the original configuration.
- Back up and exit: Stop the client and its associated service, and confirm that no leftover process is still writing.
- Confirm the correct directory: Locate the data directory using the current client documentation. If the client supports a separate config directory or portable mode, prefer the isolation method provided by the project.
- Keep the original directory: Rename the confirmed data directory. Use a backup name such as
client-data.backup-20260819; do not delete it. - Launch with default settings: Let the client create fresh user data. Do not enable TUN, import a subscription, or restore all settings yet.
- Restore in layers: Import a known-good configuration first and check whether the core starts. Then restore necessary rules and overrides, and enable the system proxy or TUN last.
If the client still crashes with an empty data directory, the old configuration is probably not the only cause; review system crash logs and version-compatibility requirements. If restoring one item causes the failure again, preserve the before-and-after difference—it is more useful for diagnosis than a full reinstall. To restore the old directory, exit the program first, keep the new directory from this test, and restore the original name to avoid mixing two databases or caches directly.
Post-recovery verification and a troubleshooting report checklist
Seeing the window again is only the first step. First confirm that the UI and core remain stable, then verify the local listening port, and only afterward test proxy traffic. The example below uses an HTTP mixed port listening on 127.0.0.1:7890; choose an HTTPS address you are authorized to access and that is reachable from the current network. The example address may still be affected by local network conditions.
# macOS / Linux
curl --proxy http://127.0.0.1:7890 --connect-timeout 10 --max-time 20 -I https://example.com
# Windows: call curl.exe explicitly
curl.exe --proxy http://127.0.0.1:7890 --connect-timeout 10 --max-time 20 -I https://example.com
The 10-second connection timeout and 20-second total timeout here are diagnostic limits, not latency scores. Seeing only 200 Connection established does not prove that the target request succeeded; also check the subsequent TLS and HTTP results. If you are still using the minimal configuration above, traffic will go direct. To verify a real proxy exit, restore a valid node and its corresponding rules, then confirm the matched policy in the connection records.
Keep reproducible details when submitting a report
- Client name, full version number, the core’s
-voutput, and the operating system version and architecture. - Package type, whether portable mode or service mode is enabled, and whether TUN is on.
- The reproduction sequence, such as “default launch works → configuration import works → core exits after enabling overrides.”
- When the failure occurred, the first specific error, the exit code, and nearby redacted log entries.
- The results of testing the default data directory, testing the minimal configuration, and checking the port separately.
If the issue appeared only after a single client update, send the evidence above to the relevant project. Before choosing another client, read the client selection guide to confirm platform and core support; for configuration issues, check each item against the configuration reference. Reproducing the issue and isolating it to one step makes a verifiable fix much easier than repeatedly reinstalling.