Clash "Port Already in Use" Error: Find the Conflicting Process and Change the Mixed Port
Bind failures on startup usually mean port 7890 or another port is already taken. Here's how to find the conflicting process on Windows, macOS, and Linux, plus the steps to change ports in the config file and client.
Why You're Seeing "Port Already in Use"
When the Clash core starts, it needs to listen on a handful of local ports: the mixed port (mixed-port, default is usually 7890) handles both HTTP and SOCKS5 traffic, the external controller port (external-controller, usually 9090) feeds the dashboard status data, and some clients also open a separate HTTP-only port. If any of these ports is already taken by another program on your machine, the core can't complete the bind system call. Logs typically show something like address already in use or bind: permission denied, and in the client UI this shows up as the core failing to start, the proxy toggle refusing to turn on, or the status flipping back to "not running" a few seconds after launch.
There are three usual culprits behind this kind of conflict: having two proxy tools installed at once (say, Clash alongside another V2Ray client), a leftover Clash process from last time that didn't shut down cleanly and is still holding the port, or — less often — a system service or router utility that happens to sit on a nearby port range. The fix is straightforward either way: first confirm exactly who's holding the port, then decide whether to kill that process or just move Clash to a different port.
Step 1: Identify the Exact Port in Conflict
The client's logs or console window usually print the offending port number. Here are the common defaults to check against first:
| Purpose | Common Default Port | Notes |
|---|---|---|
| Mixed port (mixed-port) | 7890 | Shared HTTP + SOCKS5, usually what your browser/system proxy points to |
| External controller (external-controller) | 9090 | Used by the dashboard and API to read runtime status |
| SOCKS-only port (socks-port) | 7891 | Some older configs split this out separately |
| HTTP-only port (port) | 7892 | Some older configs split this out separately |
If the log doesn't spell out a port number, go through the table above one by one — start with 7890, since it's the mixed port most clients default to and the one that collides most often.
Windows: Find the Process and Kill It
Open Command Prompt or PowerShell and check the listening state with netstat plus the port number:
netstat -ano | findstr "7890"
The last column of the output is the PID. Use that to look up the process name:
tasklist | findstr "PID"
Once you've confirmed it's an unrelated program, you can end it directly:
taskkill /PID PID /F
If the process name turns out to be Clash-related (e.g. clash-verge.exe, mihomo.exe), it's just a leftover instance from a previous session that didn't exit cleanly — kill it and relaunch the client. No port change needed in that case.
macOS: Pin Down the Process with One lsof Command
On macOS, lsof is the go-to tool — filter directly by port:
lsof -i :7890
The COMMAND column shows the program holding the port, and PID gives you the process ID. If you're sure it's safe to end:
kill -9 PID
If the port is held by a system-level service or something you'd rather not shut down (certain packet-capture tools or local dev proxies, for example), it's better to change Clash's own port instead of touching that other program.
Linux: ss, lsof, or fuser — Pick One
On Linux, ss is the recommended tool (faster than the older netstat):
ss -tulnp | grep 7890
If you don't have ss installed, lsof works the same way as on macOS:
lsof -i :7890
Or use fuser to locate and kill it in one step:
fuser -k 7890/tcp
If you're running mihomo as a systemd service, also check whether you've accidentally started two instances at once — one launched at boot and another started manually — since both would end up fighting over the same port.
Option 1: Edit the Config File Directly
If you'd rather not touch other programs, the simpler route is to just move Clash's own port. Open your config file (usually config.yaml), find the port-related fields, and set them to a value that isn't in use:
mixed-port: 7891
external-controller: 127.0.0.1:9091
allow-lan: false
You can pick any free port between 1024 and 65535 — a common trick is adding 1 or 100 to the original value so it's easy to remember. Save the file, then reload the config or restart the client for the change to take effect.
Option 2: Change It from the Client UI
Most graphical clients (Clash Verge Rev, the various Clash for Windows forks, ClashX Meta, etc.) have a dedicated port settings screen, usually under "Settings" or "General." Just enter the new value for the mixed port or controller port and save — the client will rewrite the underlying config and restart the core automatically, no need to touch the yaml file by hand. Afterward, double-check that your system proxy settings and browser extension are pointing at the same new port; a mismatch between these three is the most common reason a port change "doesn't seem to work."
How to Verify the Change Worked
Run the same lookup command again to confirm the new port is now held by Clash itself, not by something else:
lsof -i :7891
The process name in the output should be clash or mihomo-related. Then open a browser and load a few sites to test connectivity, or check the dashboard's traffic graph to make sure it's moving — that confirms the proxy chain is actually working. If you also changed the external controller port, remember to update the port in your dashboard's address bar too, or it'll show a connection failure.
Two Habits That Prevent This Next Time
- Keep only one proxy client in your startup list — the one you actually use — and uninstall or disable any idle old clients so there are fewer leftover background processes fighting for ports.
- If you regularly run two proxy tools side by side for comparison, pick fixed, non-overlapping ports for each ahead of time and write them down instead of guessing every time.
A port conflict is fundamentally a resource contention issue, distinct from a bad config or an expired subscription — don't lump them together when troubleshooting. Check the log's error message first, find out who's holding the port, then decide whether to kill the process or change the port. Following those three steps in order resolves most cases.