Check which port failed to bind
When a Clash client starts and reports address already in use, the local address and port the core is trying to listen on are usually already occupied. This happens while setting up a proxy entry on your device; it does not mean your subscription has expired or that a remote proxy node is unavailable. Repeatedly updating your subscription or switching nodes usually won’t resolve a local port conflict.
Open the client’s log and find the complete error line containing listen, bind, or in use. Note the address, port, and protocol. The example below shows the error format; it is not a live check of your device:
listen tcp 127.0.0.1:7890: bind: address already in use
Here, the port to investigate is local TCP 7890. If the log shows 127.0.0.1:9090, check the external controller interface instead of changing the proxy port. 0.0.0.0:7890 listens on all IPv4 interfaces and may conflict with a listener bound to the same port on a specific address. For [::]:7890, also consider how your system handles IPv6 dual-stack sockets.
| Config key | Purpose | What to update after changing it |
|---|---|---|
mixed-port |
Provides HTTP and SOCKS proxy access on the same port | System proxy, browser proxy, and command-line proxy variables |
port |
Dedicated HTTP proxy listener | HTTP proxy settings for apps using this listener |
socks-port |
Dedicated SOCKS proxy listener | SOCKS proxy settings in apps |
external-controller |
Control API for clients or dashboards | Control interface connection settings in the client or dashboard |
Windows: Find the process using netstat
Check the local address, listening state, and PID
Open Windows Terminal or Command Prompt and run the command below. You can usually inspect connections without elevated permissions, but viewing some process details or managing services may require administrator access.
netstat -ano -p tcp | findstr ":7890"
The columns show the protocol, local address, foreign address, state, and PID, in that order. Check the Local Address column and confirm the port is exactly 7890. Text filtering can also match a foreign address or a longer port number. For a TCP proxy listener, look for a line in the LISTENING state; don’t stop a process just because 7890 appears somewhere in its row.
You can also filter for the exact port in PowerShell to make the results easier to read:
Get-NetTCPConnection -LocalPort 7890 -State Listen |
Select-Object LocalAddress, LocalPort, State, OwningProcess
Suppose the result shows PID 4321. Run the command below to find the process name. The PID 4321 is only an example; substitute the actual PID you found.
tasklist /FI "PID eq 4321"
Identify the process before deciding whether to stop it
- Another proxy client: Exit it from the system tray menu, then check the port again. Closing its window may leave it running in the background.
- An old core process from the current client: Exit the client, then use Task Manager to check the remaining process’s path and command line. End it only after confirming it’s a leftover core process.
- A core running as a service: The service may keep running after you close the window. Stop it through the client’s service management controls so it isn’t immediately restarted after you end the process.
- Another app you still need: Leave it running and choose a different free port for Clash. Don’t stop system services just to free a port.
In Task Manager, check the PID on the Details tab. To show the command line, right-click a column heading and select Choose columns. If the process belongs to Windows, don’t force-quit it based on the port number alone; identify the related service or use a different port.
macOS and Linux: Check listeners with lsof or ss
On macOS, run the command below in Terminal. -nP keeps addresses and ports numeric, while -sTCP:LISTEN limits results to TCP listening sockets:
lsof -nP -iTCP:7890 -sTCP:LISTEN
Check COMMAND, PID, and NAME. If you suspect the listener belongs to another user and a regular query doesn’t show full details, retry with sudo if you have the required permissions. If lsof isn’t installed on Linux, use ss, which is typically provided by iproute2:
sudo ss -ltnp 'sport = :7890'
To check how a process was launched, look it up by its actual PID:
ps -p 4321 -o pid,ppid,command
Stop the process normally through its app menu or service manager first. If it’s a leftover process with no accessible management interface, send a normal termination signal, for example kill -TERM 4321. Don’t force-kill it as a first step: that won’t explain why it keeps reappearing and may skip normal cleanup.
Change mixed-port: Check which config layer takes effect
If another essential app is using port 7890, you can switch to 7892—but first check with the commands above that 7892 is free. Choosing a new number only changes the listener; it won’t automatically update connection settings in your browser, terminal, or control panel.
Here’s a partial config example for Clash Meta (mihomo) cores. It is not a complete config with proxies and rules; merge it into your existing file and keep your subscriptions, proxy groups, rules, and access authentication settings.
mixed-port: 7892
allow-lan: false
external-controller: 127.0.0.1:9090
This example changes only the mixed proxy listener to 7892 and keeps the controller on 9090. There’s no need to change the controller port unless the logs show a conflict there. allow-lan: false restricts access from your local network. If you only need to use the proxy on your own device, don’t expose it to your entire network just to fix a port conflict.
GUI client settings may override subscription files
- Note the current proxy port, controller port, and active config name, and save a restorable copy of the config.
- Look in the client settings for options such as “Mixed Port,” “Proxy Port,” or “Core Settings.” Menus vary by client, so use the setting that manages global listener parameters.
- If the client supports config overrides or merges, place local listener settings in a layer it actually supports for persistence. Don’t assume every subscription file supports the same override mechanism.
- Apply the changes, then reload or restart the core and check the logs. Whether a port change requires a restart depends on the client and core.
Direct edits to a downloaded subscription YAML may be overwritten the next time it updates. Conversely, editing the subscription file may have no effect if the client overrides the same keys with its GUI settings at startup. Check the active config, core logs, and system listeners—not just the line saved in your editor.
Also check whether standalone port or socks-port listeners are enabled. Don’t assign them the same address and port as mixed-port, and don’t define mixed-port twice at the YAML top level; duplicate keys can cause parsing errors or unpredictable overrides.
Controller port conflict: Change external-controller separately
If the error is on port 9090 while the proxy listener on 7890 is working, the problem is with the control API. You may see the GUI fail to show connections, be unable to switch proxy groups, or report that the core is disconnected; some clients may also report a startup failure. Check what’s using 9090, then consider switching to an available port such as 9091.
external-controller: 127.0.0.1:9091
After changing the port, standalone dashboards must connect to the new controller address. If the GUI client manages the control interface, update the corresponding setting so the GUI and core stay in sync. Editing only the core config can leave the proxy working while the GUI can’t connect. Keep any existing secret authentication and update dashboards that need access; don’t disable authentication to troubleshoot.
Don’t change the control interface to 0.0.0.0:9091 to try to fix the conflict. This exposes the interface more broadly and may still conflict with another listener. The control interface and mixed proxy listener are separate settings. Change only the one that conflicts to make the fix easier to verify and roll back.
Update system and app proxy settings to avoid using the old port
After changing the mixed port to 7892, apps still pointing to 127.0.0.1:7890 will continue to fail. GUI clients often update the system proxy when you enable it, but this depends on the client. Apply the new port first, then toggle the system proxy off and on, and check the address the system actually shows.
- Windows 11: Go to Settings → Network & internet → Proxy → Manual proxy setup → Set up under Use a proxy server, then check the address and port. If you use an automatic configuration script, also check the proxy address it provides.
- macOS 13 and later: Go to System Settings → Network → your current connection → Details → Proxies. Check which of Web Proxy (HTTP), Secure Web Proxy (HTTPS), and SOCKS Proxy are enabled.
- Firefox: Go to Settings → General → Network Settings → Settings. A separate manual proxy won’t automatically follow changes to your system proxy.
- Terminals and developer tools: Check
HTTP_PROXY,HTTPS_PROXY, andALL_PROXY, plus proxy addresses configured separately in Git, your editor, or containers.
A mixed port accepts both HTTP and SOCKS requests, but apps still need the right protocol. For example, set an HTTP proxy address to http://127.0.0.1:7892. For tools that support remote DNS resolution through a SOCKS proxy, use socks5h://127.0.0.1:7892. HTTPS websites use an HTTP proxy to establish a tunnel; that doesn’t mean the local proxy address should start with https://.
TUN mode routes traffic through a virtual network interface; it is not the same as a system HTTP proxy. A browser working in some TUN setups doesn’t prove the old 7890 setting is fixed. Likewise, a conflict on a regular mixed port doesn’t mean you need to uninstall the TUN device. Test the proxy listener by explicitly specifying the new port to avoid confusion about the traffic path.
Verify the fix and make sure it persists after restart
Check the listener first, then test a real request
Check port 7892 again to confirm it’s being used by the expected core process, and verify that the logs no longer show a bind failure. Then use curl to connect explicitly to the new listener. In Windows PowerShell, use curl.exe to avoid conflicts with command aliases that may use the same name.
curl.exe -I --connect-timeout 5 --max-time 15 --proxy http://127.0.0.1:7892 https://example.com/
On macOS or Linux, use the same arguments with curl. The 5-second and 15-second values set the connection timeout and total request timeout, respectively; they are not speed test results. This example assumes the local proxy doesn’t require authentication. If yours does, provide credentials using your existing method and don’t paste passwords into public logs.
- Local connection refused: First check that the new port is listening, the address matches, and the core is still running.
- Request reaches the core but times out on the way out: Check connection logs for the matching rule, proxy node, and DNS. A working listener doesn’t guarantee the rest of the connection path is healthy.
- curl works but the browser doesn’t: Check the browser’s separate proxy, proxy extensions, automatic configuration script, and existing connections before changing ports again.
- Browser works but the dashboard doesn’t: Check the controller address and authentication. Don’t mistake a control interface issue for a proxy listener problem.
Restart the client and check again
After testing, exit and relaunch the client normally, then confirm the listener is still on port 7892. If the problem often returns after startup, check login items and service mode. Keep only the startup entry you need to prevent old and new clients from competing for the same port.
If the TCP query shows no listener but the bind still fails, recheck the log timestamp, address, and protocol. On Windows, address already in use and access permissions point to different causes; the latter may involve excluded port ranges or security policies. Use the command below to view TCP excluded port ranges, but don’t delete system reservations:
netsh interface ipv4 show excludedportrange protocol=tcp
The fix is complete when all four conditions are met: the core listens on the expected port, system and app settings point to the new listener, the control interface connects, and the settings persist after restart. To roll back, first make sure the original port is free, then restore the old settings and sync the system proxy. When temporarily exiting the client, also turn off the system proxy it configured so the system doesn’t keep sending requests to a stopped local port.