Clash port 7890 is already in use: find the process and change mixed-port
Find the process using port 7890, decide whether to stop it or change mixed-port, then sync system proxy and browser settings.
First, identify the problem: failed to bind, or incorrect proxy address?
Follow this order: find the process using the port → decide whether to quit the old instance or change ports → update proxy settings → verify the listener and test a request. Don’t reinstall the client just because a website won’t load. A port conflict happens while the local listener is starting and is usually unrelated to an expired subscription or slow server.
7890 is a common setting, not a port that Clash or mihomo must use. Depending on the active configuration, the client may use it as an HTTP proxy port or a mixed port. Check the client logs for errors mentioning listen, bind, and a port number.
listen tcp 127.0.0.1:7890: bind: address already in use
This is a typical error indicating that the TCP port at that address can’t be bound again. Windows may also report, “Only one usage of each socket address is normally permitted.” If the log says permission denied or reports an access error, check for port reservations and system policy restrictions too; don’t assume another process is using the port.
- Logs clearly report a bind failure: Run the system commands below to find the process listening on the port.
- The core is listening normally, but the browser reports a proxy connection failure: First check whether the browser and system proxy still point to the old port.
- Only certain websites won’t load: Check your rules, DNS, and proxy server. Don’t keep changing the local port.
Windows: Find the process using port 7890 by PID
Method 1: Query the listening port with PowerShell
Open PowerShell on Windows 10 or Windows 11 and run the command below. An empty result means this query found no listener on that TCP port. If you get a permissions error, try an administrator terminal.
Get-NetTCPConnection -LocalPort 7890 -State Listen -ErrorAction SilentlyContinue |
Select-Object LocalAddress, LocalPort, OwningProcess
Note the process ID in the OwningProcess column. Suppose the result is 6420; look up the process name, path, and launch command. This number is only an example—use the PID returned by your own query.
Get-Process -Id 6420 | Select-Object Id, ProcessName, Path
Get-CimInstance Win32_Process -Filter "ProcessId = 6420" |
Select-Object ExecutablePath, CommandLine
Don’t rely on whether the name contains Clash. The desktop app and core often run as separate processes, and the same mihomo.exe may be launched by a tray client, a Windows service, or a manual command. The executable path and launch arguments can help identify which installation it belongs to.
Method 2: Query from Command Prompt
netstat -ano -p tcp | findstr ":7890"
tasklist /FI "PID eq 6420"
Check netstat results manually. Look for a row where the port in the “Local Address” column is exactly 7890 and the state is LISTENING. A remote address containing 7890, a state of ESTABLISHED, or a local port of 78901 is something else.
macOS and Linux: Check listeners and background services
macOS: Use lsof to find TCP listeners
Open Terminal and find the process listening on port 7890. If you can’t see all the details as a regular user, try adding sudo.
sudo lsof -nP -iTCP:7890 -sTCP:LISTEN
In the results, COMMAND is the program name, PID is the process ID, and NAME is the listening address. Quit the tray app and run the command again. If the port is still listening, a separate core process or background service may still be running; that doesn’t mean quitting the app had no effect.
Linux: Use ss to check the port and process
sudo ss -ltnp 'sport = :7890'
Here, -l shows listening sockets only, -t limits results to TCP, -n keeps ports in numeric form, and -p displays associated processes. To check UDP, run the command below separately. TCP and UDP are different transport protocols, so a UDP result alone doesn’t tell you whether the TCP port is in use.
sudo ss -lunp 'sport = :7890'
If the process reappears as soon as it exits, check whether systemd, a user service, or another process manager is restarting it. Identify the actual service unit before stopping it instead of repeatedly force-killing the process. For container deployments, check the host’s port mappings: two containers can both listen on internal port 7890, but they can’t both map it to the same host address and port.
Stop the old process or change mixed-port to 7891?
The deciding factor is whether the process using the port still needs to run, not “whoever started first is right.” If an old client was launched twice, quit it from the tray menu. If the port is needed by another proxy or development service, assign a different port to the current Clash instance.
| What you found | Recommended action | What to check |
|---|---|---|
| The old client is running twice | Quit the old client normally | Check for duplicate startup entries |
| The app is closed, but the service is still running | After confirming what it is, stop it through its client or service manager | The service may automatically restart the core |
| Another required program is listening on port 7890 | Change the current mixed-port to 7891 | Check that port 7891 is free first |
| No listener found, but access is still denied | Check port reservations and permission restrictions | Don’t blindly delete system reservations |
Only consider stopping a process after confirming what it is and saving any work you need. Try the program’s own quit option first. For a core started from the command line, press Ctrl + C in its terminal. Windows taskkill /PID 6420 /F forcefully terminates a process, so use it only if normal shutdown fails. Don’t copy the example PID.
If Windows shows no listener but access errors persist, check the TCP excluded port range. Virtualization or container components can sometimes affect which ports are available. If you find a reserved port, choosing another free port is usually safer than changing the system’s reserved range.
netsh interface ipv4 show excludedportrange protocol=tcp
netsh interface ipv6 show excludedportrange protocol=tcp
Change mixed-port: edit the right field and make the change stick
mixed-port accepts both HTTP and SOCKS proxy connections on the same listening port. It isn’t a subscription URL, a proxy server’s port, or the controller API port. If the active configuration uses a separate port or socks-port, changing only mixed-port may not change the existing entry point.
Check that port 7891 is free, then back up your current configuration. The snippet below can be merged into the top level of a configuration file; it isn’t a complete subscription configuration with proxies and rules. For a proxy used only on this device, keep it bound to the local interface.
config.yaml: Top-level listener setting
mixed-port: 7891
allow-lan: false
bind-address: 127.0.0.1
- Keep it at the top level: Don’t put
mixed-portunderdns:,tun:, or a proxy definition. - Replace the existing key: Don’t append another field with the same name at the end of the file. Duplicate keys can cause parsing errors or inconsistent behavior.
- Check separate proxy ports: If
port: 7890is still present, the existing HTTP listener may continue to conflict. Change or remove the old listener field as needed. - Keep the controller port separate:
external-controllerlets a client or dashboard control the core; it isn’t an HTTP proxy address for browsers.
Why does it revert to 7890 after saving?
A desktop client may generate the final YAML from a global port setting, configuration overrides, or merged configuration. Local edits to a subscription file may also be overwritten the next time it updates. So use the client’s persistent port setting or override mechanism whenever possible. Menu names vary between client versions; don’t assume one client’s “Settings” path applies to every Clash client.
After changing the setting, reload the configuration or restart the core using the client’s controls, then check the logs for the new listening address. Seeing 7891 in a settings field only confirms that the setting was saved—not that the core successfully bound to the port. For more on configuration fields, see the YAML guide.
Update the old port in system proxy, browser, and terminal settings
When you change the port from 7890 to 7891, the core starts listening on the new port, but other apps don’t all update automatically. A common issue is that the core starts normally while the Windows system proxy still points to 127.0.0.1:7890, causing browsers that follow the system proxy to report connection failures.
Where to check system and browser settings
- Windows 11: Go to Settings → Network & internet → Proxy → Manual proxy setup → Set next to “Use a proxy server,” then check the address and port. If the client manages the system proxy, toggle its “System Proxy” setting off and on first, then return here to verify the result.
- macOS: Go to System Settings → Network → Details for your current network connection → Proxies. Check each enabled web proxy, secure web proxy, or SOCKS proxy. The port should match the active listener.
- Firefox: Go to Settings → General → Network Settings → Settings. “Use system proxy settings” follows the system settings; “Manual proxy configuration” requires you to update the port separately.
- Chromium-based browsers: These usually follow the system proxy, but launch arguments and proxy extensions can override it. If only one browser is affected, check its independent proxy settings.
If you use an automatic proxy configuration script (PAC), check whether it still returns the old value, PROXY 127.0.0.1:7890. An HTTP proxy can also tunnel HTTPS sites using CONNECT, so don’t change the local proxy address to https://127.0.0.1:7891 just because you’re visiting an HTTPS site.
Update terminal environment variables separately
Terminal apps may use HTTP_PROXY, HTTPS_PROXY, or ALL_PROXY instead of the desktop system proxy. To update the HTTP proxy address in the current PowerShell session, run:
$env:HTTP_PROXY = "http://127.0.0.1:7891"
$env:HTTPS_PROXY = "http://127.0.0.1:7891"
On macOS or Linux, use this in a typical shell. If you also set proxy variables with different capitalization, ALL_PROXY, or app-specific settings, check that none still point to 7890. Different programs don’t all use the same precedence.
export http_proxy=http://127.0.0.1:7891
export https_proxy=http://127.0.0.1:7891
Final checks: Verify the listener, test a request, and restart
- Check the new listener: Replace 7890 with 7891 in the commands above and confirm that the listening process belongs to the current client. If the old port is still in use, check whether it belongs to a program you intend to keep running.
- Send a request through the proxy explicitly: Don’t rely only on a page cached by your browser. Run the command below to confirm you can connect through the new entry point.
- Check that the change persists: Quit and restart the client normally, then check the port again. Check once more after a subscription update to make sure your persistent override wasn’t overwritten.
On Windows, use curl.exe to avoid differences caused by the curl alias in some PowerShell environments. On macOS and Linux, use curl.
curl.exe --noproxy "" --proxy http://127.0.0.1:7891 --connect-timeout 5 --max-time 15 -I https://example.com
curl --noproxy "" --proxy http://127.0.0.1:7891 --connect-timeout 5 --max-time 15 -I https://example.com
The 5-second connection timeout and 15-second total timeout are test limits, not speed guarantees. If you can’t connect to 127.0.0.1:7891, check that the listener and configuration are active. If the proxy tunnel is established but you then see a TLS, upstream connection, or destination server error, focus on the proxy server, rules, or destination site. Seeing 200 Connection established alone doesn’t mean the request succeeded; check the output that follows.
Once the explicit proxy request succeeds, remove the proxy options from the command and test the system proxy path in your browser. Changing the local entry-point port doesn’t change how rules route traffic or make a proxy server faster. These checks help distinguish a resolved local port conflict from a separate network issue, so you don’t end up reinstalling the client over and over. For other connection issues, see Troubleshooting.