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 field | Purpose | What to check |
|---|---|---|
mixed-port: 7890 | Accepts both HTTP and SOCKS proxy connections through one entry point | Browsers, system proxy settings, and command-line tools should connect here |
port: 7891 | Dedicated HTTP proxy entry point | Check whether it duplicates the mixed port |
socks-port: 7892 | Dedicated SOCKS proxy entry point | Check the standalone SOCKS listener and the settings in apps that use it |
external-controller: 127.0.0.1:9090 | Provides a management API for clients or dashboards to control the core | Not 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
portorsocks-portis 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-controllerprovides the management API. Bind it to127.0.0.1and 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.1and the port to17890. 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
- Check the listening process: query
17890again 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. - 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. - 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.
- 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.