Clash Reports Port Already in Use on Startup: Full Guide to Finding the Blocking Process and Changing Ports

Port 7890/9090 conflicts are a frequent cause of Clash startup failures. This guide covers commands for finding the blocking process on Windows, macOS, and Linux, plus the full steps for safely changing ports in the config file and the client.

Why the "port already in use" error happens

When the Clash core starts up, it needs to bind a few fixed ports to serve proxy traffic: the mixed proxy port (usually 7890, configured as mixed-port; older versions may split it into separate port and socks-port fields), the external controller port (usually 9090, configured as external-controller), and sometimes an additional DNS listening port. If any of these ports is already claimed by another process on the system, the operating system refuses to bind it again. The core logs an "address already in use" or "bind: address already in use" style error, and the client either bounces the start button right back, shows the connection status as permanently disconnected, or pops up an error dialog.

Port conflicts generally come from three sources. The first is duplicate launches: two Clash-family clients installed on the same machine (for example both Clash Verge and a legacy Clash for Windows install), or a leftover zombie process from the last time the app didn't fully quit, still holding the port in the background. The second is a genuine port collision: another tool also happens to use 7890 or 9090, commonly some development/debugging proxies, corporate VPN clients, network testing tools, or even certain database or message queue services whose default ports fall in a nearby range. The third is system-level port reservation — on Windows in particular, certain system services reserve a range of ports that can happen to include 7890, and in these cases Task Manager often shows no obviously matching process name.

The troubleshooting approach is always the same two steps: first confirm exactly what is holding the port, then decide whether to close that process or simply move Clash to a different port. In most cases, changing the port is the easier and lower-risk fix, since it doesn't require touching any other software's configuration.

Finding the blocking process on Windows

Open Command Prompt or PowerShell and use netstat to find the process ID (PID) tied to the port:

netstat -ano | findstr "7890"

The number in the last column of the output is the PID. Look it up in Task Manager, or use this command to get the process name:

tasklist | findstr "PID"

If port 9090 also reports a conflict, swap the port number in the command and run it again. Once you've confirmed the process is unrelated to Clash, you can end it directly, or open that software's settings and change its own port instead. If the process turns out to be a leftover Clash instance itself (for example a stray clash-verge.exe or mihomo.exe hanging in the background), manually ending that process in Task Manager and restarting the client usually fixes it.

Note: some security software or system-reserved port ranges prevent netstat from showing a real process (PID shows as 0 or a system process). In that case, changing Clash's own port is the fastest fix — don't waste time chasing down the blocker.

Finding the blocking process on macOS

Open Terminal and use lsof to check the port directly:

lsof -i :7890

The COMMAND column shows the name of the process holding the port, and PID shows its process number. Swap in 9090 for the other port. To end the blocking process:

kill -9 the_matching_PID

A common scenario on macOS is having both Clash Verge and an older ClashX-family client installed at the same time — both use the same default ports, so if one is running in the background (for example set to launch at login), starting the other triggers a conflict. Check Login Items in System Settings and keep only one client set to launch automatically.

Finding the blocking process on Linux

On Linux, ss is the recommended tool (faster than the older netstat, and bundled by default on most modern distros):

ss -tulnp | grep 7890

If ss isn't available, fall back to netstat or lsof:

lsof -i :7890

Once you have the PID, end it with kill:

kill -9 the_matching_PID

Anyone running the core (mihomo/Clash core) as a systemd-managed service should be careful here: if the core was started via a systemd unit, simply killing the process may cause systemd to restart it automatically according to its restart policy, re-claiming the port right away. In this case, stop the service unit with systemctl stop first, confirm the port is actually free, and then investigate the root cause of the conflict instead of repeatedly killing the process.

Changing the port in the config file

If the port is held by another program you can't or don't want to close, the cleanest fix is to move Clash to a different port rather than fighting with the other software. The relevant fields sit near the top of config.yaml:

mixed-port: 7891
allow-lan: false
external-controller: 127.0.0.1:9091
secret: ""

Change mixed-port to a free port (pick something in the 1024–65535 range that doesn't clash with common services — 7891 or 17890 both work fine), and change the port in external-controller the same way. Note that this field uses the full "address:port" format, so don't drop the listening address before the colon. Some older config files still use separate port (HTTP proxy port) and socks-port (SOCKS5 proxy port) fields instead of the combined mixed-port — the same logic applies, just change both to free numbers.

Tip: after changing the port, you need to restart the client or reload the config for it to take effect — simply saving the YAML file without restarting the core won't apply the change automatically.

Changing the port in the client interface

If you'd rather not edit the YAML directly, mainstream clients expose port fields in their settings screens. The general path looks like this:

  1. Open client settings

    Find the "Settings" or "General" section and locate the field labeled "Mixed Port," "HTTP Port," "SOCKS Port," or "Proxy Port."

  2. Enter the new port number

    Enter a port you've confirmed is free — it's worth verifying with the commands above first that the port is currently unused.

  3. Update the controller port too

    If the client separately lists an "External Controller Port" or "API Port" (corresponding to external-controller), change that to a free value as well, as long as it doesn't clash with the proxy port.

  4. Save and restart the service

    After saving, the client will usually prompt you to restart the core or the app for the change to take effect — follow the prompt rather than repeatedly clicking connect before restarting.

  5. Check the system proxy settings

    If the system's network proxy settings have a manually entered port number (rather than following the client automatically), update that port number too, otherwise traffic will still point at the old port and fail to connect.

Verifying the new port works

After restarting the client, confirm the new port is listening from the command line first, rather than jumping straight to a browser test (browser tests are affected by system proxy settings, DNS caching, and other factors, so they're less direct). On Windows, run netstat -ano | findstr "new_port" again — a LISTENING state means the core has successfully bound the port. On macOS and Linux, run lsof -i :new_port and look for the Clash core's process name (commonly mihomo, clash-meta, or the client's bundled core executable name).

Once you've confirmed it's listening correctly, double-check that the port entered in your system proxy or browser extension matches the new port — both sides need to agree before the connection actually works. If your client has a built-in "test connection" or "latency check" feature, it should now return a result normally instead of a connection-refused error.

A few habits that prevent port conflicts

A few habits go a long way toward avoiding this problem next time. First, keep only one Clash-family client installed on a given device, and uninstall or fully quit the old version before installing a new one, so two clients don't fight over the same background port. Second, if the machine also runs other proxy tools or a development environment that expects specific ports, set Clash's port to something clearly uncommon from the start (a five-digit high port, for example) to avoid collisions altogether. Third, whenever you do change a port, note down what you changed it to so it's easy to reference later — especially in team settings where a config file is shared, it's worth adding a comment near the top of the file documenting any port changes.

If the same conflict keeps recurring against the same program (say a fixed corporate application that permanently holds 9090), the more permanent fix is to change Clash's default port once and for all, rather than freeing up space every single time — that way both the config file and the client setting only need updating once, and normal use won't keep getting interrupted.

Download Clash