Clash Client Startup Crashes: Config Syntax, Port Conflicts, and Leftover Processes
When a client won't open or crashes right after launch, the cause usually falls into one of four categories: config syntax errors, port conflicts, leftover core processes, or missing runtime libraries. This article walks through platform-specific log locations and step-by-step elimination.
Why "won't open" and "crashes on launch" need separate handling
Users often lump these two symptoms together when reporting issues, but the troubleshooting paths differ. "Won't open" usually means clicking the icon produces no response at all, and the process list shows no trace of the executable — this is typically a system permissions issue, a missing runtime library, or a corrupted install package. "Crashes on launch" means the process did actually start, but the window flashes briefly or appears momentarily before disappearing on its own — common causes here are config parsing failures, core-side port conflicts, or a leftover local core process holding onto resources. Telling these two apart is the first step to a quick diagnosis — blindly reinstalling rarely fixes the root cause, especially for port conflicts and leftover processes, where the problem persists no matter how many times you reinstall.
It's also worth noting that Clash-family clients (including implementations built on the Clash Meta (mihomo) core) are architecturally split into two layers: a GUI on top, and a core process underneath that actually handles traffic. A GUI crash doesn't necessarily mean the core is broken, and a core crash can also show up as a frozen, unresponsive GUI. When troubleshooting, it's best to first confirm which layer the problem is actually in before treating it.
Step one: check the logs, don't guess
Nearly every Clash-family client keeps local run logs, and the error messages in those logs tell you far more than repeated restarts ever will. Common log locations:
- Windows: the
logsfolder inside the client's install directory, or the corresponding client subfolder under%APPDATA%. - macOS: the folder named after the client under
~/Library/Logs/, or the "Open Log Folder" entry inside the app. - Linux: when running as a systemd service, use
journalctl; standalone executables usually print logs directly to standard output in the terminal.
If the client offers a "launch from terminal" or similar debug option, use it first — a crashing GUI disappears before you can read the error, but terminal output stays put and lets you review it line by line.
When asking others to help diagnose an issue, pasting the raw log is far more useful than describing "it won't open." Logs usually spell out whether it's a config parsing failure, a port binding failure, or a missing dynamic library — and those keywords map directly to the four categories below.
Cause one: config file syntax errors
Clash config files use YAML, which is extremely sensitive to indentation and special characters. Hand-editing a config file, or generating one through a poorly written subscription conversion script, can easily cause the core to exit immediately during parsing. Common syntax issues include:
- Mixing spaces and tabs for indentation, or inconsistent indentation levels among sibling fields.
- Unescaped colons or hash characters inside strings, which the parser mistakes for a new key-value pair or the start of a comment.
- Rule providers or proxy groups referencing names that don't actually exist, causing the core to error out during validation.
- Newer core versions deprecating old field names, while the config still uses the old syntax, resulting in a field type mismatch.
How to troubleshoot: first run the config through any online or local YAML validator to check indentation and basic syntax, then cross-check field names against the client's documentation to confirm they're supported by the current core version. If you can't pin down which line is at fault, try commenting out sections incrementally — keep only the most basic port, mode, and DNS fields, confirm the client starts, then add back proxy nodes and rule providers one group at a time until the error reappears. That pinpoints exactly which section is causing trouble.
Don't just delete the whole field mentioned in the error message to "make the error go away" — that only masks the real problem. If you've confirmed the faulty config came from the subscription itself, contact the subscription provider, or use the client's "config override" feature for a local fix, rather than repeatedly hand-editing the raw subscription file long-term.
Cause two: port already in use
When the Clash core starts, it needs to bind local ports — the HTTP/SOCKS proxy port, the external controller port (usually somewhere around 9090), and the virtual network adapter involved when TUN mode is enabled. If any of these ports are already taken by another program, the core fails to bind and exits, which shows up in the GUI as a crash or a "failed to connect to core" message.
Common causes: another proxy tool that hasn't fully exited is still running, a leftover core process from a previous session is still listening on the old port, or a local dev tool (like a local debug server) happens to use the same port range. Troubleshooting steps:
- Windows: run
netstat -ano | findstr 7890in the command line (replace the port number with the one actually set in your config file), note the returned PID, then check Task Manager or runtasklist /FI "PID eq your-PID"to identify which program it is. - macOS / Linux: run
lsof -i :7890orsudo lsof -i :9090to see what's holding the port — the process name usually makes it obvious whether it's a leftover core or another proxy tool.
Once you've identified the culprit, either terminate the process holding the port, or change the mixed port / external controller port in the client's settings to a free value. If you regularly switch between multiple proxy tools on the same machine, it's worth assigning each tool its own port range so you don't have to manually chase down conflicts every time.
Cause three: leftover core process
When a client exits abnormally (forced process termination, a system sleep interruption, or being cut off mid-update), the core's child process sometimes gets detached from GUI management and keeps running in the background as an orphaned process. This leftover process keeps holding onto the previously configured port, so the next time you start the client normally, the freshly launched core fails to bind that same port — the client crashes immediately after launch, and the log explicitly says the address is already in use.
Cleanup by platform:
- Windows: open Task Manager, find the core's process name (naming varies by client, but executables often contain
mihomo,clash, or similar), terminate it manually, then restart the client. - macOS: search Activity Monitor for the same process name keyword, or batch-clean with
pkill -f mihomo(confirm first that this won't accidentally kill another unrelated program with the same name). - Linux: run
ps aux | grep mihomoto find the PID and terminate it withkill -9 PID; if the client runs as a systemd-managed service, prefersystemctl stopfollowed bysystemctl startto avoid the service state drifting out of sync with the actual process state.
If this keeps recurring, check whether the client or system is force-killing related processes during updates, and check whether the client has a setting like "clean up core process on exit" that should be kept enabled.
Cause four: missing runtime library
Some clients' GUIs are built on system-bundled or third-party runtime frameworks. If the system is missing the matching runtime version, the app crashes right at startup — often without even generating a log file, because the program exits before it gets far enough to write one.
Common scenarios:
- Windows: missing the Visual C++ runtime or the WebView2 component — this is especially common on older Windows versions, or on machines that just had a fresh OS reinstall without the usual runtime libraries. Check whether WebView2 is installed via the system's component manager, and install the official runtime redistributable if it's missing.
- Linux: an outdated dynamic library version bundled with the distro, or missing GTK/WebKitGTK GUI dependencies — installing the relevant packages via your package manager usually resolves it.
- macOS: the OS version is below the client's minimum requirement, and the newer app relies on system APIs the older OS doesn't support — the only fix here is upgrading the OS or switching to a client version that supports your current macOS version.
A simple way to check whether this is the cause: run the client's executable directly from a terminal instead of double-clicking the icon. The terminal usually prints exactly which dynamic library or component is missing — far more informative than the GUI's generic "crashed" message.
Quick self-check table for all four causes
| Symptom | Likely cause | Key action |
|---|---|---|
| Window flashes briefly on launch then disappears | Config file syntax error | Validate YAML indentation; isolate by commenting out sections |
| Error connecting to core, or a port error message | Port already in use | Check the offending process with netstat / lsof |
| Repeated restarts still crash immediately, log says address already in use | Leftover core process | Manually terminate the old core process, then restart |
| Double-clicking the icon does nothing, no log generated | Missing runtime library | Run the executable directly from a terminal to see the error |
Verification order after fixing the issue
After resolving the problem, verify in this order rather than jumping straight back to your full complex config:
- Start the client with the simplest possible default config first, and confirm the core launches normally and the external controller port is reachable.
- Gradually switch back to your original subscription config, and check that it parses and updates the node list correctly.
- Before enabling system proxy or TUN mode, first confirm the network works fine in plain proxy mode, then layer on advanced features one at a time — this makes it much easier to pinpoint which layer caused it if something breaks again later.
- If the original problem was a port conflict, remember to check whether the port entered in your system proxy settings still matches the port the client is currently using, in case the port changed but the system proxy settings weren't updated to match.
If the problem persists after going through all four categories above, it's worth keeping the full logs and config file (with any personal credentials in your subscription link redacted) before seeking further support — this significantly cuts down the back-and-forth needed to diagnose the issue.