How to Troubleshoot Clash System Proxy Not Working: Separate Browser and Terminal Checks

System proxy enabled but traffic still bypasses it? Browsers and terminal tools handle proxies differently. Follow two paths: check browser settings and extension conflicts, then verify terminal variables and proxy ports to pinpoint the failure.

First, identify which layer is failing

“System proxy enabled” only means the client attempted to write HTTP and HTTPS proxy addresses to the operating system settings. It does not mean every program will read them. Browsers such as Chrome and Edge usually follow the system proxy; Firefox can use the system settings or maintain its own proxy configuration. Terminal tools such as Git, curl, npm, Python, and container tools often bypass the system proxy and read environment variables or their own configuration files instead.

Do not start by switching nodes, reinstalling the client, or repeatedly re-importing the subscription. Break the path into four parts: whether the Clash core is running, whether a listening port exists, whether the target program sends connections to that port, and which rule a connection matches after entering Clash. Layer-by-layer checks reveal whether the fault lies in the client, operating system, application, or rule configuration.

Observed result Check first Common causes
Neither browser nor terminal traffic is proxied Core, port, and configuration status Core not started, port conflict, or configuration load failure
Browser works, terminal connects directly Terminal environment variables and tool configuration Command-line tools do not read the system proxy
Terminal works with an explicit proxy, browser connects directly System proxy and browser settings System proxy not written, extension override, or browser using an independent configuration
Request appears in the log, but the site does not open Rules, nodes, DNS, and certificate errors Matched REJECT, unavailable node, or abnormal domain resolution
Regular apps work, but games or UWP apps fail TUN, loopback restrictions, and UDP support The app does not use HTTP proxying or requires UDP forwarding

Record the actual port instead of assuming 7890

Many configurations use 7890 as the mixed port, but this value is not mandatory. Different clients may show separate HTTP, SOCKS5, and mixed ports, and the configuration file may override them. Open the client’s “Settings” → “Port Settings” or “Settings” → “Clash Settings” and record the address and port currently listening. Use 7890 in the commands below only if the interface shows it as the mixed port.

mixed-port: 7890
allow-lan: false
mode: rule
log-level: info

mixed-port accepts both HTTP and SOCKS5 connections. If the configuration uses port: 7890 and socks-port: 7891 separately, the test command must use the matching protocol. Sending a SOCKS5 request to an HTTP-only port often results in a connection reset or proxy handshake failure, rather than a clear “wrong port type” message.

Browser path: check system proxy settings and extension overrides

Step 1: Verify the proxy address in the operating system

In Windows 11, go to “Settings” → “Network & Internet” → “Proxy” and check whether “Use a proxy server” is enabled. The address is usually 127.0.0.1, and the port should match Clash’s current HTTP or mixed port. If the client says the system proxy is enabled but the Windows page still shows an old port, turn the client’s system proxy switch off and on again.

In macOS, go to “System Settings” → “Network” → the current network interface → “Details” → “Proxies”. Common setups select both “Web Proxy (HTTP)” and “Secure Web Proxy (HTTPS)”, use 127.0.0.1 as the server, and use the HTTP or mixed port shown by the client. When only a SOCKS proxy is configured, whether an app uses it depends on the app’s own implementation.

Do not enter the node server address in the system proxy settings. These settings should point to the local Clash listener, such as 127.0.0.1:7890; Clash handles node addresses, authentication, and transport parameters through its configuration. Writing a remote node port directly into the system proxy usually prevents the expected protocol handshake.

Step 2: Rule out browser-specific proxy settings and extension conflicts

Chrome and Edge read the system proxy by default, but proxy-switching extensions can override this path. First test in an incognito window; if extensions are allowed to run in incognito, temporarily disable proxy-related extensions from the extensions page as well. Check replacement extensions for SwitchyOmega, enterprise proxy policies, packet-capture tools, and debugging proxies. When multiple tools control the proxy, the one that writes last or has higher priority determines the actual route.

Firefox requires a separate check under “Settings” → “General” → “Network Settings” → “Settings”. Choose “Use system proxy settings” to follow the value written by Clash; with “Manual proxy configuration”, enter the current local port; “No proxy” connects directly. Firefox’s “Auto-detect proxy settings for this network” also does not necessarily follow the system proxy.

Step 3: Use the logs to confirm that browser requests reach Clash

  1. Open the client’s “Logs” page and keep the log level at info.
  2. Close pages that are automatically refreshing in the browser to reduce background-request noise.
  3. Open a new tab and visit an HTTPS site that has not been opened before.
  4. Search for the domain in the log and check the connection source, matched rule, and final policy.

If the domain never appears in the log, the problem is between the browser and the local port. Continue checking the system proxy, browser policies, and extensions. If the log shows rules such as MATCH or DOMAIN-SUFFIX, along with a proxy group or DIRECT, the browser has handed the request to Clash. Next, check rule selection and node status.

A cached page displayed by the browser cannot prove that the current proxy works. In Developer Tools, open the “Network” panel, enable “Disable cache”, and perform a hard refresh. You can also watch Clash’s “Connections” page: a new connection should show the target domain, network type, upload and download traffic, and matched route.

Terminal path: verify the port with an explicit proxy

Terminal behavior cannot be inferred from browser results. The most reliable approach is to specify a proxy explicitly for a single command first. If that succeeds, configure environment variables or tool-specific parameters. If it fails too, return to checks for the local port, core status, and firewall.

Test an HTTP proxy directly with curl

In Windows PowerShell 5.1, curl may be an alias for Invoke-WebRequest, so run curl.exe explicitly. Recent versions of Windows 10 and Windows 11 usually include curl. Assuming the mixed port is 7890, run:

curl.exe -v -x http://127.0.0.1:7890 https://example.com/

On macOS, Linux, Git Bash, or systems with standalone curl installed, run:

curl -v -x http://127.0.0.1:7890 https://example.com/

If verbose output includes Connected to 127.0.0.1 and a CONNECT request to the HTTPS target, curl has connected to the local proxy. If an HTTP status code follows and the target domain appears in the Clash log, the proxy path is working. An immediate Connection refused means nothing is listening on that port, or the port is incorrect.

Use SOCKS5 and let Clash resolve the domain

For SOCKS5 tests, use socks5h. The trailing h tells the proxy to resolve the domain, avoiding interference from local DNS results. Use the SOCKS port or mixed port:

curl -v --proxy socks5h://127.0.0.1:7890 https://example.com/

The main difference between socks5:// and socks5h:// is where the domain is resolved. The former typically resolves the name locally and sends the IP to the proxy; the latter includes the domain in the SOCKS request. When troubleshooting domain pollution, domain-based routing, or unstable local DNS, prefer socks5h.

Configure environment variables for the current terminal session

In PowerShell, you can set a proxy for the current window only. The variables disappear when the window closes, making this useful for troubleshooting:

$env:HTTP_PROXY="http://127.0.0.1:7890"
$env:HTTPS_PROXY="http://127.0.0.1:7890"
curl.exe -v https://example.com/

On macOS, Linux, WSL, or Git Bash, set both uppercase and lowercase variables because different programs do not follow exactly the same conventions:

export HTTP_PROXY=http://127.0.0.1:7890
export HTTPS_PROXY=http://127.0.0.1:7890
export http_proxy=http://127.0.0.1:7890
export https_proxy=http://127.0.0.1:7890
curl -v https://example.com/

Also check NO_PROXY and no_proxy. If the target domain, a domain suffix, or a matching wildcard appears in the exclusion list, the program will bypass the proxy. The following setup sends only local addresses directly:

export NO_PROXY=localhost,127.0.0.1,::1
export no_proxy=localhost,127.0.0.1,::1

Git, npm, and Python may each store proxy settings

Git can read environment variables, but it may also retain an old port in its global configuration. Check the current source before deciding whether to change it:

git config --global --get http.proxy
git config --global --get https.proxy
git config --show-origin --get-regexp "http\..*proxy"

To explicitly configure a local proxy for Git, use:

git config --global http.proxy http://127.0.0.1:7890
git config --global https.proxy http://127.0.0.1:7890

Use npm config get proxy and npm config get https-proxy to inspect npm’s settings. Python’s pip may read HTTPS_PROXY, and it can also be tested with a one-time argument:

python -m pip install --proxy http://127.0.0.1:7890 package-name

Old ports in tool configurations can easily lead to false conclusions: the browser may have switched to the new 7890, while Git still connects to the previous 7897. After changing Clash’s listening port, recheck environment variables, Git configuration, npm configuration, IDE terminals, and container environments.

Confirm that the core and port are actually listening

View listening processes on Windows

In PowerShell or Command Prompt, run the following command to check whether 7890 is in the LISTENING state:

netstat -ano | findstr :7890

The process PID appears at the end of the output. You can then query the process name:

tasklist /FI "PID eq process-number"

If the process using the port is not the current Clash client, change the listening port or stop the conflicting process. If there is no output, return to the client and check the core status and configuration errors. A configuration parse failure may leave the graphical interface open while preventing the proxy port from being created as expected.

View listening addresses on macOS and Linux

lsof -nP -iTCP:7890 -sTCP:LISTEN

Linux also supports:

ss -lntp | grep 7890

When listening on 127.0.0.1:7890, only local programs can access the port, which is common for desktop use. To let other devices on the LAN connect, enable “Allow LAN” in the client, set allow-lan to true in the configuration, and confirm that the listening address and system firewall permit access from the relevant network. Do not switch to a LAN-wide listener merely to troubleshoot a local browser.

Once a connection appears in the log, inspect the rules

Clash rules usually match from top to bottom, and the first match takes effect. A domain may first match DOMAIN, DOMAIN-SUFFIX, or a rule set; only when none of those match does it reach the final MATCH. If a test request matches REJECT, the connection is actively refused; with DIRECT, the local network connects to the destination directly.

If switching to Global mode restores connectivity, the port, system proxy, and node path are generally working, so the problem is likely in the rules or policy group. Record the rule name and policy group in the log, then check whether the group has selected a working node. Do not stay in Global mode indefinitely to hide rule problems: LAN addresses, software updates, and local services may be sent through the proxy unnecessarily.

When the system proxy cannot reach an app: determine whether TUN is needed

The system proxy mainly covers applications that actively support HTTP or SOCKS proxies. Some games, command-line tools, store apps, virtual machines, containers, and software with custom network stacks do not read system settings. These programs may connect directly even when the browser works perfectly.

TUN mode uses a virtual network interface to capture more IP traffic and pass it to a compatible core such as mihomo. It suits applications that cannot be configured with a proxy, require UDP, or need their connections handled centrally. TUN is not a “system proxy boost switch”; it depends on system permissions, routing, DNS interception, and the state of the virtual network adapter.

Three checks before enabling TUN

After enabling it, check the client log for a successful TUN interface creation message, then see whether the target app’s connections enter Clash. On Windows, if only specific UWP apps cannot connect, also consider app loopback restrictions; some clients provide a UWP Loopback helper. This is a different layer from system proxy settings in a regular desktop browser.

If enabling TUN makes the entire system unable to resolve domains, disable TUN first to restore connectivity, then check DNS settings, the virtual network adapter, and conflicts with other VPNs. Do not change nodes, rules, DNS, and routes simultaneously, or it will be difficult to identify what caused the change.

Close the loop: a reproducible troubleshooting sequence

  1. Confirm that the client core is running and that the configuration page shows no parse errors.
  2. Read the actual HTTP, SOCKS5, or mixed port from the client interface instead of assuming a port number.
  3. Use netstat, lsof, or ss to confirm that the port is listening.
  4. Temporarily switch to Global mode and select a confirmed working node.
  5. In the browser path, verify the system proxy, Firefox’s independent settings, and proxy extensions.
  6. Open the Clash log, visit a new domain, and confirm whether the request reaches the core.
  7. In the terminal, explicitly specify the proxy with curl -x instead of relying on environment variables first.
  8. After the explicit test succeeds, set HTTP_PROXY, HTTPS_PROXY, or a tool-specific proxy.
  9. Switch back to Rule mode and use the log to confirm the matched rule, policy group, and final route.
  10. Evaluate TUN, UWP loopback, or container networking only when the application does not support the system proxy.

The key is to test one variable at each step. If the browser fails but explicit curl succeeds, check the system proxy and browser. If the browser works but the terminal fails, check environment variables and tool configuration. If neither can connect to the local port, check the core and listener. If the request reaches the log but the result is abnormal, check rules, nodes, and DNS. Once “system proxy not working” is split into these observable outcomes, reinstalling the client is usually unnecessary.

Download Clash