Troubleshooting 12-minute read

What to Do When Clash Port 7890 Is Already in Use: Find the Process and Change the Mixed Port

When startup reports “address already in use,” find the process occupying the port on Windows, macOS, or Linux, then safely change mixed-port or the external controller port.

Read the error first: identify whether the proxy port or control port is in conflict

When Clash or mihomo starts with bind: address already in use, the core cannot bind the local address and port it tried to listen on. The usual cause is another process already listening on the same address. Start by checking local listeners; there is no need to buy another subscription or switch proxy nodes. The remote server port in your subscription and 7890 on your computer are in two different places.

Open the client log and copy the full line containing listen, bind, and the port number. The examples below show how to identify the fields; not every client uses the same prefixes:

listen tcp 127.0.0.1:7890: bind: address already in use
listen tcp 127.0.0.1:9090: bind: address already in use
Config fieldPurposeWhat to check
mixed-port: 7890Accepts both HTTP and SOCKS proxy connections through one entry pointBrowsers, system proxy settings, and command-line tools should connect here
port: 7891Dedicated HTTP proxy entry pointCheck whether it duplicates the mixed port
socks-port: 7892Dedicated SOCKS proxy entry pointCheck the standalone SOCKS listener and the settings in apps that use it
external-controller: 127.0.0.1:9090Provides a management API for clients or dashboards to control the coreNot a browser proxy port

The ports in this table are example config values, not defaults shared by every client. Use the log and the effective config as your source of truth. If the log shows 9090, check the control interface first; changing only mixed-port from 7890 will not resolve a conflict on the control interface.

Windows: Find the process using netstat and PowerShell

1. Find the PID listening on port 7890

Open Start and search for “Terminal” or “PowerShell.” Run the query first; if you get a permissions error when inspecting another user’s process or stopping a service, reopen it as an administrator. These commands only read status—they do not stop processes:

netstat -ano -p tcp | findstr ":7890"

Look for a row with a local address of 127.0.0.1:7890, 0.0.0.0:7890, or [::]:7890 and a state of LISTENING. The last column is the PID. A result containing :7890 could also be a remote connection, so don’t assume every matching row is a listener. To filter specifically for local listeners, run:

Get-NetTCPConnection -LocalPort 7890 -State Listen -ErrorAction SilentlyContinue |
  Select-Object LocalAddress, LocalPort, OwningProcess

2. Check the process path to distinguish a tray app from a background service

Suppose the query returns PID 1234; replace the number below with the actual PID. Check the process name first, then its executable path and startup arguments:

tasklist /FI "PID eq 1234"

Get-CimInstance Win32_Process -Filter "ProcessId = 1234" |
  Select-Object ProcessId, ExecutablePath, CommandLine

A common cause is an old client still running in the system tray while a newly launched client starts another core. Another possibility is mihomo already listening as a service while the GUI starts a second instance. First, choose “Exit” from the relevant client’s menu, or verify the PID under Task Manager → Details. For a confirmed background service, open the Services console and check its name and executable path before deciding which service to stop.

If the process doesn’t exit normally, you can stop the confirmed PID with Stop-Process -Id 1234. Save your config first and make sure the process isn’t a service another user relies on. Don’t use a command that kills every proxy process by name.

3. No listener found, but binding still fails

Check the latest log again and distinguish address already in use from access permissions. The latter may point to a system-reserved port or security policy, so don’t treat it as a routine port conflict. On Windows, you can also check the TCP excluded port ranges:

netsh interface ipv4 show excludedportrange protocol=tcp
netsh interface ipv6 show excludedportrange protocol=tcp

If the port you want falls within one of the listed ranges, choose an available port outside it. Don’t delete system exclusions just to keep using 7890; virtualization, containers, and network sharing may depend on them.

macOS and Linux: Check the listening address, then identify what launched it

macOS: Use lsof

Open Applications → Utilities → Terminal and run the following command. -nP keeps addresses and ports numeric to avoid confusing name lookups; -sTCP:LISTEN shows TCP listeners only.

sudo lsof -nP -iTCP:7890 -sTCP:LISTEN

Check COMMAND, PID, and NAME in the output. If the PID is 1234, check its launch command next:

ps -p 1234 -o pid,ppid,user,command

Quit the relevant client from the menu bar first. If you started the core manually, return to the original terminal and press Control-C. Use kill -TERM 1234 only after confirming it’s a leftover process that’s safe to stop. If the PID changes and the port starts listening again, check System Settings → General → Login Items & Extensions and any launchd services you configured to find what’s restarting it.

Linux: Use ss and check systemd services

sudo ss -ltnp 'sport = :7890'
ps -p 1234 -o pid,ppid,user,args

In ss, -l means listening, -t selects TCP, -n uses numeric output, and -p shows the process. If the output points to a systemd-managed core, first confirm the actual unit name. Run the commands below only if mihomo.service is the unit you installed:

systemctl status mihomo.service
sudo systemctl stop mihomo.service

For a user service, use systemctl --user to inspect and manage it. If you’re running Docker, also check host port mappings in docker ps; the process occupying host port 7890 may be a published container port, not the desktop client you’re troubleshooting.

Change mixed-port: choose an available port, then update the effective config

If another app needs to keep using 7890, assign a different entry point to your Clash client, such as 17890. This is only an example; it may already be in use on your system. First, replace 7890 with 17890 in the query commands above and check availability.

Minimal local listener config

mixed-port: 17890
allow-lan: false
bind-address: 127.0.0.1

external-controller: 127.0.0.1:19090
secret: "local-api-19090-change-before-use"

This YAML snippet illustrates the listener fields only; it does not include proxy nodes, policy groups, or rules, and cannot replace a complete subscription. It also shows the control port set to 19090; keep the existing value if the control port isn’t in conflict. Replace the example secret with a randomly generated string of your own, and update the management dashboard to match.

  • Keep each top-level field unique: edit the existing mixed-port; don’t append a second key with the same name at the end of the file. Use spaces for YAML indentation, not tabs.
  • Check separate ports: if port or socks-port is enabled, make sure neither listens on the same address and port as the mixed port. If you only need the mixed entry point, disable the extra listeners if your client supports it.
  • Confirm the listening scope: for local use, keep allow-lan: false. Don’t listen on every network interface just to resolve a conflict; doing so could expose the proxy entry point to more devices.
  • Keep the control interface local: external-controller provides the management API. Bind it to 127.0.0.1 and set a secret; don’t expose it directly to the public internet.

Subscription files, overrides, and the runtime config

Desktop clients typically merge the subscription with local settings to generate the config passed to mihomo. Editing a downloaded YAML cache directly may be undone by the next subscription update; editing a temporary runtime file may also be lost on restart. Look for a client option such as “Mixed Port,” “Port Settings,” or “Overrides.” The exact label depends on the client version.

Save your changes and restart the core—not just close the settings window. Then check the listening port in the startup log or rerun the listener query. If you use the mihomo binary directly, run mihomo -t -f config.yaml from the config directory to check the file. Passing a syntax check doesn’t guarantee the port can be bound; verify the result after starting the core.

After changing the port, update system proxy settings and command-line tools

Once the core listens on 17890, apps still sending traffic to 7890 will fail to connect or may connect to a different, older proxy instance. Try turning the client’s system proxy off and back on, then check the address saved by the operating system.

  • Windows 11: Settings → Network & internet → Proxy → Manual proxy setup. For a manual proxy, set the server to 127.0.0.1 and the port to 17890. If you use a PAC file, check the destination specified by its rules instead of changing only the manual proxy settings.
  • macOS: System Settings → Network → your active connection → Details → Proxies. Check the ports for any enabled web proxy, secure web proxy, or SOCKS proxy.
  • Standalone apps: Custom proxy settings in browser extensions, download managers, editors, and Git won’t necessarily follow system settings. Check each one separately.

Command-line tools may also read proxy environment variables. Check the current proxy variables in Windows PowerShell and in your macOS or Linux terminal:

# Windows PowerShell
Get-ChildItem Env: | Where-Object Name -Match 'proxy'

# macOS / Linux
env | grep -i proxy

For example, if you had HTTPS_PROXY=http://127.0.0.1:7890, update it to the new port. Here, http:// specifies how to connect to the local HTTP proxy; it doesn’t mean the destination website must use HTTP. After changing persistent environment variables, you usually need to reopen the terminal; already-running processes won’t pick up the new values.

TUN mode takes over traffic routed through a virtual network interface, which is a separate layer from the mixed-port listener. Turning on TUN won’t free 7890 if another process is using it; apps explicitly configured to use an HTTP or SOCKS proxy still need their port settings checked. Switching between rule and global modes also won’t resolve a local listener conflict.

Verify the fix: check the listener, a proxy request, and the config after restart

  1. Check the listening process: query 17890 again and confirm the PID belongs to the expected Clash or mihomo instance. Then check the original port from the error to see whether another service is still using it.
  2. Check the startup log: make sure there are no new bind errors. If you still see errors for 9090, 7891, or other ports, troubleshoot each one separately; one successful listener doesn’t mean everything is fixed.
  3. Send an explicit proxy request: use the curl command below instead of relying on a browser page or its cache to tell you whether the proxy works.
  4. Verify the settings persist: check again after restarting the client. After the next subscription update, confirm that your local override is still taking effect.
# Windows PowerShell
curl.exe --noproxy "" -I --connect-timeout 5 --max-time 15 --proxy http://127.0.0.1:17890 https://example.com/

# macOS / Linux
curl --noproxy "" -I --connect-timeout 5 --max-time 15 --proxy http://127.0.0.1:17890 https://example.com/

Here, --noproxy "" clears the proxy bypass list for this request. --connect-timeout 5 and --max-time 15 set the time limits for connecting and for the entire request, respectively. These are test options, not speed measurements.

If you immediately get a connection error for 127.0.0.1:17890, go back to checking the listener and address. If the local proxy connects but the request later fails with a TLS, DNS, or remote timeout error, focus on the proxy node, DNS, and rules instead. For an HTTPS test, 200 Connection established only confirms that the proxy accepted the CONNECT tunnel request; also check the destination’s response and the client log.

Common questions: reinstalling, firewalls, and running two clients

Will reinstalling Clash fix port 7890 being in use?

If another running core is using the port, reinstalling the current client usually won’t stop that process. Finding its source by PID is more direct than repeatedly uninstalling the app. Deleting config files could also remove your subscription and overrides, so back up any local settings you need first.

Will turning off the firewall fix “address already in use”?

A firewall mainly affects whether connections can get through; it doesn’t free a listening port already in use by an app. A bind failure and devices on your local network being unable to connect are different problems. Don’t start by turning off the firewall to fix a local port conflict.

Can two Clash clients run at the same time?

They can if configured with different listener and control ports, but you’ll also need to coordinate the system proxy, TUN routes, and DNS takeover. For typical desktop use, it’s easier to maintain one core responsible for system networking. If you need to run a second instance for testing, give it a separate local proxy entry point and don’t let it compete for the system proxy or TUN.

The log reports a UDP port conflict. Do I use the same commands?

The commands above mainly check TCP listeners. If the log explicitly reports UDP, check that protocol separately: on Windows, use Get-NetUDPEndpoint -LocalPort 7890; on macOS, use sudo lsof -nP -iUDP:7890; on Linux, use sudo ss -lunp 'sport = :7890'. TCP and UDP use separate port spaces, so an empty TCP query doesn’t prove that the UDP port is free.

The fix is complete when the expected core listens successfully, requests through the new port work, and the settings survive a restart and subscription update. If connection issues remain, visit the Help Center to distinguish DNS, subscription, and rule issues, or review mihomo config responsibilities in Advanced Config.

Download Clash