Clash Port Already in Use? Find the 7890 Conflict and Change the Mixed Port

Find the process using a port on Windows, macOS, or Linux, learn where to change mixed-port and the controller port, and see which settings to update afterward.

Check the logs first: which listening address failed to start?

When a Clash client reports that a port is already in use, the core usually failed to bind to the specified address. The most common causes are another proxy client running in the background or a service-managed core running alongside one started manually. Don’t reinstall or kill every process with “Clash” in its name. Identify the failed port and the process using it first; that usually narrows the fix considerably.

Search the client logs for terms such as bind, listen, and address already in use. Windows may also report, “Only one usage of each socket address is normally permitted.” The log below is an example; prefixes vary by core version:

listen tcp 127.0.0.1:7890: bind: address already in use

This message points to TCP port 7890 on the local loopback address, not a remote node’s server port. Changing the node port in your subscription won’t fix a local listener conflict. If the log says permission denied or “access is denied,” also check system-reserved ports, permissions, and security policies; don’t assume another process is using the port.

Configuration fieldPurposeWhat to check
mixed-portAccepts both HTTP and SOCKS proxy requests on the same listenerOften 7890; check your actual configuration
port / socks-portProvides separate HTTP and SOCKS proxy listenersCheck whether either listener duplicates the mixed listener’s address and port
external-controllerProvides the control API used by the client UI or dashboardOften 127.0.0.1:9090; this is not a web proxy port
dns.listenReceives DNS queriesIf the conflict involves port 53 or a custom DNS port, check the DNS service separately

Port conflicts also depend on the listening address and transport protocol. 0.0.0.0:7890 listens on all IPv4 interfaces and may conflict with 127.0.0.1:7890. Whether an IPv6 wildcard listener also covers IPv4 depends on the OS and socket settings. TCP and UDP ports with the same number are separate listening resources, so check the protocol shown in the log.

Windows: Find the process using port 7890 by PID

Check the listener, then identify the process

Run these commands in PowerShell. The first filters for a TCP listener on port 7890; the second checks the executable path. If the example output shows PID 6248, use that number in the second command. In practice, use the PID returned on your machine.

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

Get-Process -Id 6248 | Select-Object Id, ProcessName, Path

If you prefer Command Prompt, you can use the built-in netstat and tasklist commands:

netstat -ano -p tcp | findstr ":7890"
tasklist /FI "PID eq 6248"

findstr filters text and may also match a remote port or a number such as 78900. Check that the “Local Address” column actually ends in :7890 and that the state is LISTENING. A TIME_WAIT entry alone doesn’t mean a process is still listening; don’t mistake every connection record for the source of a conflict.

  1. If another proxy client is using the port, quit it normally from its system tray menu, then check the port again.
  2. If the current client’s core is using the port, check whether service mode is enabled while another core instance was started manually.
  3. If a new PID appears immediately after the process exits, open Task Manager → Services, or run services.msc, and check whether a background service is restarting it.

No listener found, but binding still fails

First confirm the error is for port 7890, not 9090 or another address. If the Windows log points to an access-permission issue, check the excluded TCP port range:

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

Hyper-V, containers, and related networking components can reserve ports. If the port you want falls within an excluded range, it’s usually safer to choose a verified free port than to remove an unfamiliar system reservation. Running the client as an administrator won’t necessarily bypass this restriction.

macOS and Linux: Tell desktop clients apart from background services

macOS: Use lsof

Open Applications → Utilities → Terminal and look for listeners on TCP port 7890. The -nP flags keep addresses and ports numeric, avoiding distracting name lookups. If permissions hide some results, retry with sudo.

lsof -nP -iTCP:7890 -sTCP:LISTEN
ps -p 6248 -o pid,ppid,command

Check the COMMAND and PID columns, then use the second command to inspect the full launch command. Some clients stay in the menu bar after their windows close; quit from the menu bar instead. To check whether an app launches at sign-in, go to System Settings → General → Login Items & Extensions. The final section name may vary slightly between macOS versions.

Linux: Use ss

On Linux, ss can show listening addresses and process details. These commands check TCP and UDP separately; run the UDP command only if the log or feature involved points to UDP.

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

If systemd manages the process, killing it may trigger an automatic restart. Try systemctl status 6248 to find the service associated with the PID; for a user service, check systemctl --user. Once you’ve confirmed the actual unit name, stop it with the appropriate stop command. Don’t assume every installation uses the same service name.

With Docker or other containers, also check the host port mapping. Port 7890 inside a container and publishing port 7890 on the host are two separate settings. If the conflict is on the host, changing only the container’s internal configuration may not free the host port.

Change mixed-port in the active configuration, not just a subscription copy

If the conflicting process needs to stay running, assign Clash a different proxy port. This example changes 7890 to 7893. Port 7893 is just an example and may already be in use; check it with the same commands before making the change.

First, confirm which configuration the client actually uses

A GUI client often builds its runtime configuration from the subscription, overrides, and client port settings. Editing the downloaded YAML alone may be undone by a subscription update—or may not affect the core at all. UI labels vary, so look for “Port,” “Mixed Port,” or “Mixed Port” settings, and use the client’s persistent settings or override mechanism where available.

This is a top-level configuration snippet for mihomo, not a complete subscription configuration. Merge it into your existing configuration rather than replacing the whole file. If a key with the same name already exists, change its value instead of adding a duplicate.

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

mixed-port accepts both HTTP and SOCKS requests, but it can’t bind to the same address alongside a separate port or socks-port. Check existing listeners and don’t set them to 7893 as well. The client may also affect the listening address when it generates the configuration, so confirm the result with an OS-level port check.

When managing the mihomo configuration directly, you can start by checking its syntax and configuration. These commands assume the actual config.yaml is in the terminal’s current directory:

mihomo -t -f ./config.yaml

A successful configuration check doesn’t guarantee the port can be bound: validating configuration and opening a listener at runtime are separate steps. After applying the configuration, check the logs and port status. GUI clients may need a core restart to apply listener changes fully; a saved value in the input field isn’t enough to confirm success.

Port 9090 conflict: don’t use it as a proxy port

external-controller is the listening address for the control API. The client UI uses it to read connections, switch policies, or change runtime settings. It is not an HTTP proxy. If 127.0.0.1:9090 is in conflict, changing only mixed-port won’t help. Likewise, setting your browser’s proxy to port 9090 won’t route web requests correctly.

If you manage the configuration and control panel yourself, you can change the controller address to the example below after confirming the port is free:

external-controller: 127.0.0.1:9093

After the change, update the control address in any external dashboard and keep the existing secret authentication setting. If the GUI client manages the controller port, change it in the client’s settings where possible. Overriding the core field without updating the UI connection settings can leave the core forwarding traffic while the UI shows it as disconnected.

Settings to update after changing the proxy port

After changing the port from 7890 to 7893, any app still pointing to the old address will fail to connect. A client status of “Core running” only confirms that the core started; it doesn’t mean your browser, terminal, or other tools have switched to the new address.

Where it’s usedWhat to update
System proxyReapply the client’s system proxy setting and confirm the address is now 127.0.0.1:7893
Browser proxy extensionChange manually configured HTTP or SOCKS ports to 7893; check separately if the extension follows system settings
Terminal environment variablesUpdate HTTP_PROXY, HTTPS_PROXY, ALL_PROXY, and any lowercase variables actually in use
Developer toolsCheck the proxy address saved in Git, package managers, and IDEs
Devices on your local networkIf LAN access was enabled, update the port and check the firewall. Don’t use 127.0.0.1 as the address of another device.

On Windows 11, check Settings → Network & internet → Proxy for the manual proxy settings. On macOS, check System Settings → Network → your current connection → Details → Proxies. After the client reapplies the system proxy, confirm the actual value in system settings too, in case another tool overwrites it.

Example: change the current terminal session only

# macOS / Linux: current shell
export http_proxy=http://127.0.0.1:7893
export https_proxy=http://127.0.0.1:7893

# PowerShell: current session
$env:HTTP_PROXY = "http://127.0.0.1:7893"
$env:HTTPS_PROXY = "http://127.0.0.1:7893"

The HTTPS proxy variable still uses http:// because HTTPS destinations are reached through the local HTTP proxy’s CONNECT method; this doesn’t downgrade the destination to HTTP. If you used SOCKS before, point compatible apps to socks5h://127.0.0.1:7893. Check whether each app reads these environment variables.

TUN mode routes traffic through a virtual network interface; apps connecting directly to the mixed port use a different path. So an app still having internet access in TUN mode doesn’t prove its old 7890 proxy setting is fixed. Tools with manually configured proxies may still be using the old port.

Verify in three layers: listener, proxy request, and app connection

  1. Check the listener: Query port 7893 again and confirm the expected core is listening, with no new bind errors in the logs.
  2. Test the proxy protocol: Send a request explicitly to the new port instead of relying on the system proxy being updated.
  3. Test your usual apps: Open a browser or developer tool, then check the client’s connection list for the request and the matching rule.
# macOS / Linux
curl -I --connect-timeout 5 --max-time 15 --noproxy "" --proxy http://127.0.0.1:7893 https://example.com

# Windows PowerShell: call curl.exe explicitly
curl.exe -I --connect-timeout 5 --max-time 15 --noproxy "" --proxy http://127.0.0.1:7893 https://example.com

The test sets a 5-second connection timeout, a 15-second total timeout, and clears the proxy bypass list for this request. If it can’t connect to 127.0.0.1:7893, check whether the listener started. If the proxy connection succeeds but you then see a TLS error, upstream timeout, or policy error, focus on the node, DNS, and rules rather than changing the local port again.

Receiving an HTTP response from the destination helps confirm the request path, but doesn’t guarantee node bandwidth or that every site and app will work. Some sites may reject HEAD requests, so consider the response in context. Change one variable at a time and note the original port; this makes issues easier to isolate than changing rules, DNS, and TUN settings together.

Common questions: restarts, multiple clients, and recurring conflicts

The problem went away after restarting my computer. Should I still investigate?

If it happened only once, you can monitor it. If it returns after every sign-in, check startup apps and background services. A restart may change the startup order temporarily without fixing the underlying competition for the same port. Keeping the PID, executable path, and logs from a conflict is more useful than repeatedly restarting.

Can two Clash clients run at the same time?

They can use different proxy and controller ports, but system proxy settings, TUN routes, and DNS interception can still interfere with each other. For everyday use, it’s usually easier to maintain one client responsible for routing traffic. Changing only port 7890 won’t isolate every system-level setting between two clients.

I changed the port, but a subscription update changed it back to 7890. What should I do?

This usually means the change was made in a configuration layer that gets regenerated. Check the client’s port settings or persistent override feature, then review the final runtime configuration and listener after updating the subscription. Don’t rely on what the subscription editor shows to determine the value the core is currently using.

Follow the same order each time: check the logs for the address and protocol, find the listening process, decide whether to quit a duplicate instance or change the port, then update app settings and test. For the basics of importing a profile and routing traffic, see the Clash usage guide. For configuration fields, see the Protocol and configuration reference.

Download ClashChoose a client for your device