A Clash desktop client typically consists of a user interface, the Clash or mihomo core, configuration files, a database, and a system proxy control module. After double-clicking, you may see no window at all, a window that disappears immediately, a tray icon that flashes briefly, or crashes every time after importing a configuration. These symptoms look similar, but they can occur at completely different stages of startup. Instead of repeatedly reinstalling or clicking the icon, first define the failure boundary, then isolate the configuration, permissions, core, and runtime environment one by one.
First identify where the client exits
The startup sequence can be divided into four broad stages: loading the interface process, reading client settings, starting the proxy core, and applying the system proxy or TUN network settings. Identifying the stage where the client exits can significantly narrow the investigation.
No window appears after clicking
First check whether the program is already running in the background, whether all files are present, whether it has execute permission, and whether the interface dependencies can load. If the process appears in Task Manager or the system monitor and ends immediately, it usually belongs to this stage as well.
The window closes immediately
Common causes include a corrupted client settings file, invalid saved window state, missing UI runtime libraries, or legacy data that is incompatible with the new version. The core may not have started yet.
Crashes begin after importing a configuration
Focus on YAML syntax, configuration-field compatibility, rule-set files, GeoIP or GeoSite data, and whether the subscription-generated configuration exceeds the capabilities of the current core.
The client exits after TUN is enabled
Check administrator privileges, service components, virtual network interfaces, port conflicts, and security policies. If the client works in system proxy mode but fails only when TUN is enabled, changing nodes or proxy rules is usually not the first step.
Also distinguish between the interface exiting and the core exiting. Some clients keep the tray process running after the window closes; others show a notification when the core fails to start while leaving the interface usable. Use a task-management tool to observe the GUI process and core processes such as mihomo or clash separately, and record which process ends first. This sequence is more useful for diagnosis than the title of an error dialog.
Isolate corrupted configuration and unsupported fields
If the client worked normally until a subscription update, rule edit, or core switch, the configuration should be the first thing you check. YAML is sensitive to indentation, colons, and list formatting. One stray tab, a rule item with incorrect indentation, or a value containing special characters without quotation marks can cause parsing to fail.
Verify the client with a clean data directory
- Exit the client completely and confirm that both the interface and core processes have ended.
- Locate the client data directory and rename it as a dated backup directory.
- Restart the client and let it generate default settings automatically.
- Do not restore subscriptions, override scripts, rule sets, or the old database yet. Test only whether the basic interface stays running.
If the clean environment starts successfully, the program files and major system dependencies are usually fine, and the problem lies in the old data directory. Migrate content by category rather than copying everything at once. A recommended order is basic client settings, one configuration file, subscription records, rule sets, and other caches. Restart after each category so you can identify the scope as soon as the problem returns.
Test the YAML configuration separately
mihomo can test a configuration from the terminal. Executable names and supported options may differ between releases, so confirm them with the help command first. A common test form is:
mihomo -t -f config.yaml
Older Clash cores also commonly use the same test option:
clash -t -f config.yaml
A successful test only means that the current core can parse the configuration; it does not mean that every proxy node is reachable. If the test reports an unknown field, duplicate name, missing rule set, or invalid port format, fix the first error and test again. Later errors may simply be cascading results of the initial structural problem.
When migrating a configuration from another client, also verify the core family. Proxy protocols, rule providers, DNS fields, or traffic-sniffing options extended by mihomo may not be recognized by an older original Clash core. Conversely, some desktop clients transform configurations before use, so copying their runtime configuration directly into another client may bring along client-specific fields. Use the core version actually called by the target client as the compatibility reference.
Check directory permissions, system proxy settings, and TUN conflicts
Permission problems do not always appear as “access denied.” A client may open normally but fail to write configuration, replace the core, create logs, or start a background service, then exit because of an unhandled exception. Portable builds stored in read-only directories, data copied from another account, execution restrictions on managed devices, and security software blocking child processes can all produce similar symptoms.
Windows checks
- Place the client in a regular directory that the current account can read and write to. Do not run it directly from inside an archive.
- Check Task Manager for leftover GUI processes, core processes, or old services with the same name. End the stale processes before starting again to prevent the database or listening ports from remaining locked.
- Normal system proxy mode usually does not require running as administrator continuously. TUN, service installation, or network-interface changes may require elevated privileges. Grant authorization only when performing those operations, as instructed by the client.
- Check whether another proxy tool is continuously changing the system proxy settings. Multiple clients controlling the same proxy port or system-proxy switch can create a startup loop.
macOS and Linux checks
- Confirm that the application or executable is in a permitted location and has the read, write, and execute permissions required by the current account.
- Check the operating system's security warning for the downloaded file. After confirming its source, complete the authorization in system settings instead of casually loosening permissions for an entire directory.
- If you use TUN, confirm that the required helper service is installed correctly and that an old service is not pointing to a program path that has been deleted.
- On Linux desktop environments, launch the client from a terminal once and inspect output related to shared libraries, the display server, permissions, and configuration paths.
TUN mode creates or controls a virtual network interface and changes routing and DNS paths. If the client runs reliably with TUN disabled, keep it in normal system proxy mode first and troubleshoot TUN separately. Check for other VPNs, virtual-machine networks, container networks, or legacy proxy services using the same interface or routes. Do not change DNS, routes, the core, and the configuration in the same test, or you will not know which change actually helped.
Verify the core file, architecture, and startup arguments
A desktop client does not necessarily embed the proxy core permanently in its main program. Some clients extract core files on first launch or during updates, some let you choose between cores, and others call the core through a background service. If the interface works but the core process exits immediately, check the following.
Does the file exist?
Check whether the core path recorded in the client settings is still valid. After moving the installation directory, clearing a cache, or an interrupted update, the path may point to a file that no longer exists.
Does the processor architecture match?
x86-64, ARM64, and other core architectures are not interchangeable. The fact that the graphical interface starts does not mean that a separately downloaded core is suitable for the current device.
Can the core run independently?
Run the core's version or help command in a terminal. This helps distinguish a core that cannot load at all from one that fails only after the client passes it arguments.
Are the listening ports available?
If another process is using the HTTP, SOCKS, Mixed, controller, or DNS port, the core will usually fail to start and record a binding error in the log.
If the client offers an “Update core” or “Switch core” feature, a crash after updating may result from an incompatible version combination. For example, the interface may still pass startup arguments that changed in the newer core, or an older client may not understand state data generated by the new core. Use a core version explicitly supported by the client instead of judging compatibility solely by version number.
If the core can display its version independently but exits immediately after loading a configuration, return to checking the configuration and data files. In addition to the main configuration, inspect MMDB, GeoSite, rule-provider caches, and external UI paths. When the configuration references a missing or unreadable file, the log often reports its exact path.
Repair UI runtimes and system components
If the client cannot start even with a clean data directory and the graphical process exits before the core runs, inspect the dependencies of the UI technology stack. Different Clash clients may use different desktop frameworks and therefore require different components, so no single runtime library is the universal answer.
Common Windows components
Some clients use system WebView components to render the interface, while native modules may require the Microsoft Visual C++ runtime. Damaged or outdated system components can cause a blank window, an instantly closing window, or a dynamic-link-library loading failure. Use the module name shown in Event Viewer or the terminal error to identify the required system component, install the version matching the client's architecture, and restart the system afterward.
If the program was upgraded by overwriting an old directory, old and new modules may also be mixed together. A safer approach is to keep a data backup, remove the old program files, and extract or install the complete new version into a separate directory. Do not mix files from different architectures or release branches in the same directory.
Common macOS and Linux components
On macOS, distinguish between the application itself failing to load, helper-service authorization failing, and a core architecture mismatch. Use the Console app to view crash reports, focusing on the exception type, termination reason, and last loaded module. On Apple silicon devices, also confirm that you downloaded the native ARM64 version or that the client explicitly supports a compatibility layer.
Launching from a terminal is usually the most direct approach on Linux. If the output reports a missing shared library, install the corresponding dependency through the current distribution's package manager rather than copying an individual library from another distribution. Wayland, X11, desktop tray implementations, and sandbox permissions can also affect the interface, but they usually do not prevent the mihomo core itself from executing, so test the GUI and core separately.
Use logs and system records to find the first meaningful error
The goal of crash troubleshooting is not to collect the most logs, but to find the first error that explains the failure before the process exits. The end of a log may contain only “process ended” or “connection closed”; the actual cause often appears several lines earlier.
- Record the exact time of the failure, accurate to the minute.
- Clear or rename old logs, then start the client only once to reduce historical noise.
- Check the client log, core log, and system crash records at the same time.
- Start reading near the first occurrence of error, fatal, panic, permission denied, address already in use, or parse failed.
- Use the file path, port number, field name, or module name in the log to perform a single focused verification.
On Windows, use the “Application” records in Event Viewer to confirm the failing module. On macOS, check crash reports in Console. On Linux, look for clues in terminal output, user logs, and system logs. If the client allows you to change the log level, temporarily raise it to debug before reproducing the issue, then restore the normal level afterward to avoid generating excessive logs over time.
Common log messages and corresponding actions include:
- Configuration parsing failed: Locate the YAML line and the structure above it, then test again with the current core.
- Unsupported field: Check the configuration source, core type, and version. Do not simply remove the reported field and continue using an otherwise unknown configuration.
- Port binding failed: Find the process using the port, or change the listening port after confirming what it is used for.
- Access denied: Check the specific path, file owner, directory permissions, or service authorization instead of broadly expanding permissions across the entire disk.
- Database or cache corrupted: Back up and move the affected cache so the client can regenerate it. Do not delete the subscription source and custom configuration at the same time.
- Core exited unexpectedly: Start the core independently in a terminal with the same configuration to determine whether the cause is the configuration, a data file, or client arguments.
Restore functionality with the fewest changes possible
A reusable recovery sequence is: end leftover processes, back up the data directory, start in a clean environment, test the configuration with the current core, then check ports, permissions, and the TUN service. If the clean environment still crashes, investigate program files, system components, and architecture compatibility. This sequence separates user-data problems from runtime-environment problems and reduces unnecessary reinstalls.
When restoring old data, import only one configuration at a time and first use rule mode or a direct-connection policy to verify interface stability. After confirming that the core keeps running, test node connections, DNS resolution, rule providers, and automatic subscription updates. For crashes triggered by an old subscription, fetch the subscription again instead of continuing to copy corrupted cache files.
If you need to report the problem to the client project, provide the client version, core version, operating system version, processor architecture, reproduction steps, and sanitized error logs. Remove or redact subscription URLs, proxy server addresses, authentication details, and personal paths from the configuration first. Clearly stating “exits as soon as the interface opens,” “exits after loading a specific configuration,” or “exits after enabling TUN” is more useful than simply writing “Clash crashes.”