When Clash says the port is already taken

You updated Clash Verge Rev, double-clicked the tray icon to start the core, and instead of a clean launch you see a log line that refuses to go away: bind: address already in use, or the GUI shows a one-line error about failing to listen on 127.0.0.1 with a familiar four-digit port. Nothing is “corrupted” in the mystical sense—you almost always have a Clash port in use situation: some process on Windows already owns that TCP port, and the new instance cannot bind to it.

People still search for Clash for Windows because that name became shorthand for desktop Clash on PC. Modern builds embed the Mihomo (Clash Meta) core behind UIs such as Clash Verge Rev or FlClash. The networking behavior is the same: every inbound listener needs an exclusive port. When Windows netstat shows the port in LISTENING state with another program’s PID, your fresh start loses the race. This article gives copy-friendly commands, explains the difference between the mixed port your browser may use and the external-controller REST surface, and shows how to change either side deliberately instead of rebooting until luck returns.

If you have not installed a maintained client yet, grab a build from our Clash download page first. The steps below assume a Mihomo-compatible profile with typical keys such as mixed-port, port, socks-port, and external-controller.

ℹ️
Security note: The external-controller exposes an HTTP API on loopback by default. If you ever bind it to 0.0.0.0 for remote access, pair it with secret and firewall rules. This guide keeps examples on 127.0.0.1, which is appropriate for single-user desktops.

Know which port failed before you fight the wrong battle

Clash-related “port taken” errors are not interchangeable. Your YAML (or the GUI’s generated config) defines several independent listeners, and each can collide separately:

  • Mixed port (mixed-port): Often something like 7890, serving HTTP and SOCKS together for local apps and system proxy scenarios.
  • HTTP / SOCKS legacy keys (port, socks-port): Still present in older templates; some subscriptions assume fixed numbers here.
  • External controller (external-controller): Typically 127.0.0.1:9090, where the dashboard and REST tools talk to the core. This is the control port in day-to-day language even though nothing stops you from moving it.

When the log only says “failed to listen” without a port, open the client’s raw log window and scroll to the earliest line mentioning listen tcp or : plus digits. Write that number down—it is the one Windows netstat must filter for. Mixing up 7890 with 9090 is the most common copy-paste error after an import from a subscription tutorial: you stop a process on the wrong port and wonder why nothing improved.

Step 1: Map the port to a PID with netstat

Open Command Prompt or PowerShell as a normal user; administrator rights are not required merely to inspect listeners on your own session. The classic sequence is:

netstat -ano | findstr :9090

Replace 9090 with the port from your error line—examples include 7890, 7891, 7892, or any custom value you set in the profile. The -a flag shows all connections and listening endpoints, -n prints numeric addresses (faster to read), and -o adds the owning PID. You are looking for a row whose State column reads LISTENING and whose local address ends with your chosen port.

If the output scrolls past too quickly, narrow it further:

netstat -ano | findstr LISTENING | findstr :9090

On Windows 11, some users prefer PowerShell’s object pipeline. This alternative is equivalent in spirit and also surfaces the PID:

Get-NetTCPConnection -LocalPort 9090 -State Listen -ErrorAction SilentlyContinue

Either way, record the last column from netstat—that integer is what Task Manager will resolve to an executable name. If no rows appear, either the conflicting process already exited, you mistyped the port, or the listener bound to a specific interface that your filter excluded. Re-run netstat -ano | findstr LISTENING and eyeball nearby addresses for IPv4 versus IPv6 notations such as [::] versus 0.0.0.0.

Tip: Keep one Notepad scratch line with three fields—port number, PID, and process name—as you troubleshoot. When something flakes again weeks later, that breadcrumb saves you from repeating the same netstat hunt from memory.

Step 2: Turn the PID into a process you recognize

Press Ctrl + Shift + Esc to open Task Manager. On modern Windows, switch to the Details tab. Right-click the header row, choose Select columns, and enable PID (Process Identifier) if it is hidden. Sort by PID and locate the number from netstat.

You might see clash.exe, mihomo.exe, verge-mihomo.exe, or another wrapper—the exact filename varies by packaging. Sometimes the occupant is not Clash at all: local development servers, database tools, or another VPN product often squat on 7890-ish ports because template authors reused familiar numbers. Seeing Visual Studio Code’s helper or a Node development server on that PID means you should reconfigure that tool or move Clash instead of uninstalling blindly.

If Task Manager feels clumsy, tasklist in a command window also maps PID to image name:

tasklist /FI "PID eq 12345"

Replace 12345 with your actual PID. This one-liner is easy to paste into chat logs when you ask for community help—much more useful than a screenshot of a generic error banner alone.

Step 3: End the process-or decide you should not

If the listener is clearly a stale Clash core from a crash or failed upgrade, terminating it is reasonable. From an elevated or normal command prompt:

taskkill /PID 12345 /F

The /F flag forces termination when a polite close would hang. Afterward, re-run netstat for the same port; it should show no LISTENING line. Then start your GUI again.

If the PID belongs to something you need—say a company VPN or a database—do not kill it silently in the middle of work. Prefer changing Clash’s ports in the YAML so both tools coexist, or schedule which runs when. That is not cowardice; it is how you avoid IT tickets and ambiguous split-brain routing.

Why ghost listeners survive “exit” clicks

Tray icons lie occasionally: the UI exits while a child mihomo process stays alive, especially when the parent watchdog loses track after a forced sleep-resume cycle or a silent auto-update swap. Autostart entries can spawn a second core before yesterday’s instance finishes shutting down, producing a race on boot. When Clash port occupied symptoms appear right after logging in, check Task Manager → Startup for duplicate launchers and disable the older one.

Another scenario: you installed two different front-ends that both ship their own core and both default their external-controller to 9090. Both cannot win. The fix is not “more reboots,” it is unique ports per profile or choosing one client stack and uninstalling the other’s background service.

Step 4: Change external-controller deliberately

Open your active configuration—the file your GUI points to, often surfaced through a “profile directory” button. Locate the line resembling:

external-controller: 127.0.0.1:9090

Pick a free high port you can remember, such as 19090, and write:

external-controller: 127.0.0.1:19090

If you use secret for API authentication, keep it in place; you are only moving the socket. Save the file, restart the core from the GUI, and confirm listening status:

netstat -ano | findstr :19090

Any bookmarked dashboard URL must change to match—your browser may still point at 9090/ui until you edit it. Many Mihomo dashboards auto-detect when served through the bundled helper, but a hard-coded bookmark does not. That mismatch looks like an authentication failure when the real issue is “you are talking to the wrong port.”

For readers wiring automation, remember that switching control port values also means updating scripts that call the REST API. Search your shell profiles for the old number before you blame token rotation.

Step 5: When the mixed port or SOCKS port collides

Browser traffic and terminal tools usually hit mixed-port rather than the controller. If logs complain about 7890, adjust:

mixed-port: 7890

to another unused value, say 7893, then align Windows system proxy settings to the same integers. Our Windows 11 system proxy troubleshooting guide covers how the manual proxy table must track whatever inbound port Mihomo actually exposes; mismatch there masquerades as “Clash ignores my proxy” when the real story is “nothing is listening on the port Windows cites.”

If your subscription assumes a specific SOCKS or HTTP port, changing numbers may require revisiting app-specific proxy fields. That is expected: port flexibility trades away some copy-paste convenience from outdated forum posts.

Step 6: Verify end-to-end after edits

Once the core stays running, run three quick checks:

  • Listener check: netstat shows LISTENING for each port you configured—controller plus mixed.
  • Dashboard check: The browser UI loads against the new controller port without certificate or connection refused errors.
  • Data-plane check: A simple outbound fetch—browser or curl—proves traffic still exits through your policy group.

If the controller responds but web browsing fails, you may have fixed the Clash port conflict and uncovered a separate rule or DNS issue. That is progress: logs are now readable again. For rule-order questions after the tunnel is stable, see Clash rule routing best practices; it complements this port-level primer.

Fresh profiles, imports, and duplicate defaults

New users who paste online templates sometimes stack multiple snippets that each redefine external-controller. Depending on parser behavior, the last key wins—or the GUI merges unexpectedly. After you learn how subscription import flows into YAML, revisit merged files whenever an unexplained port reappears: duplication is easier to diagnose than “random” bind failures.

Closing: treat ports like allocated resources

The bind error is unspectacular yet stubborn: until you map ports to PIDs with Windows netstat, every workaround feels superstitious. Naming the listener, terminating the right process, or re-homing external-controller on a free TCP port closes the loop methodically. Compared with opaque all-in-one VPNs, a Mihomo-based client still rewards that one-time systems habit with logs you can trust on the next upgrade.

When you want a build whose defaults align with current security guidance, download Clash for free from our official page and experience the difference.