Clash On But Browser/Terminal Still Direct? Proxy Not Working Guide

System proxy toggle is on, yet traffic still bypasses it — this usually isn't a Clash problem itself, but the fact that browsers and terminals each maintain their own separate proxy-detection logic. This article breaks the diagnosis into three lines: registry/network settings, browser plugin conflicts, and terminal environment variables, ending with a TUN mode fallback that doesn't depend on any single switch.

What the system proxy toggle actually changes

The "system proxy" toggle in the Clash client interface essentially writes an HTTP/HTTPS proxy configuration at the operating-system level — on Windows it writes the ProxyServer key in the registry, on macOS it writes the proxy settings for a network service, and on Linux desktop environments it writes GSettings or environment variables. This configuration only takes effect for **programs that respect the system proxy setting**, and whether an app respects it is entirely up to the app itself — the OS does not forcibly intercept every outbound connection to enforce this rule.

In other words, the system proxy is a "suggestion," not mandatory forwarding. Mainstream browsers (Chrome, Edge, Firefox in default mode) read this suggestion, while most command-line tools and some older software ignore it entirely, making connections directly through their own network stack. That's why, on the same machine, a browser may already be routed through the proxy while curl in a terminal still fails to connect directly, or connects fine but bypasses the proxy entirely.

Distinguish the two kinds of "not working" first One is that the proxy configuration was never written to the system at all; the other is that it was written, but the target program never reads it. The former requires checking system settings and Clash core status; the latter requires checking the specific program's proxy logic. These are two completely different paths — mixing them up only makes debugging messier.

Line one: system-level registry and network settings

This is the most fundamental layer. If it isn't configured correctly, nothing downstream — browser or terminal — will work either.

Windows: check Internet Options and the registry

After enabling the system proxy toggle, Clash writes to the current user's HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings. The key fields are ProxyEnable (should be 1) and ProxyServer (should point to the address and port Clash is listening on, usually 127.0.0.1:7890). You can go directly to Settings → Network & Internet → Proxy and check whether the manual proxy settings match Clash's HTTP port.

macOS: check the network service's proxy configuration

On macOS, proxy settings live under each individual network service (Wi-Fi, Ethernet, etc.), not in one global location. Open System Settings → Network → the service you're using → Details → Proxies, and confirm that "Web Proxy (HTTP)" and "Secure Web Proxy (HTTPS)" are both checked, pointing to Clash's local listening port. With multiple network interfaces or services, it's easy to miss one — especially when both Ethernet and Wi-Fi are active, and only one service's proxy got updated while the other didn't.

Common pitfall After a laptop switches Wi-Fi networks, macOS sometimes silently resets the proxy setting to "off." If the proxy seems to work intermittently, check whether switching Wi-Fi networks quietly turned it off.

Line two: why browsers ignore the system proxy

Browsers bypassing the proxy usually falls into one of four scenarios, listed in order of debugging priority:

  1. The browser has its own independent proxy mode. Firefox does not follow the system proxy by default — it uses its own manual configuration under "Network Settings." You need to manually select "Use system proxy settings" in about:preferences, otherwise it makes no difference whether Clash is on or off.
  2. A proxy-management extension is installed. Extensions like SwitchyOmega take over the browser's proxy decisions. Even if the system proxy already points to Clash, if the extension is set to "direct connection" or another address, the browser actually uses the extension's configuration, not the system's. This is the easiest conflict to overlook — temporarily disable all proxy-related extensions first to confirm whether traffic routes through the proxy at all, then decide whether the extension needs separate configuration.
  3. The browser has a built-in VPN or "secure browsing" acceleration feature. Some browsers (especially certain regional builds) include a network-acceleration toggle that bypasses the system proxy and connects directly. If nothing seems to work no matter what you configure, check the browser's own settings for such a feature and turn it off.
  4. Misconfigured PAC script mode. If Clash is using an auto-configuration script (PAC) instead of a fixed HTTP proxy, the browser needs to be able to fetch that PAC file successfully. Try visiting the PAC address directly in the browser (typically http://127.0.0.1:<port>/proxy.pac) — if it fails to load, the PAC service isn't running, and switching to a fixed HTTP proxy mode is more reliable.

Suggested order: use the browser's built-in "network diagnostics" or visit a domain known to be hit by a rule, and watch whether that connection appears in Clash's connection panel. If it appears but is marked as direct, the issue is in the rules or proxy group; if it doesn't appear at all, the browser never sent the request to Clash — go back through the four points above.

Line three: why terminals ignore the system proxy

The terminal environment is the most commonly misunderstood layer — many people assume that turning on the system proxy automatically makes command-line tools follow it, but Linux and macOS terminal toolchains generally don't read GUI proxy settings at all. They look at **environment variables** instead.

Standard environment variable checklist

Most command-line tools that follow Unix conventions (curl, wget, git, package managers, etc.) read the following environment variables:

export http_proxy="http://127.0.0.1:7890"
export https_proxy="http://127.0.0.1:7890"
export all_proxy="socks5://127.0.0.1:7891"
export no_proxy="localhost,127.0.0.1,.local"

These lines only take effect in the current terminal session and disappear once the window closes. For persistence, add them to ~/.zshrc, ~/.bashrc, or your shell's startup script, and run source once to apply them immediately. Windows Command Prompt and PowerShell work similarly — use $env:HTTP_PROXY / $env:HTTPS_PROXY for the current session, or set them permanently through system environment variables.

Common pitfalls

ToolReads env varsExtra config needed
curl / wgetYesNone
gitNo (by default)http.proxy setting
npm / yarnNo (by default)proxy / https-proxy setting
docker CLIYes (needs per-container setup)Container env vars or daemon.json
Python requestsYesNone (follows standard env vars)

TUN mode: a fallback that doesn't depend on any single switch

If, after checking all three lines above, a handful of programs still stubbornly refuse to use the proxy — or you'd simply rather not configure environment variables and browser extensions one by one — the more thorough approach is switching to TUN mode. TUN mode creates a virtual network adapter on the system and intercepts all outbound traffic at the network layer, no longer relying on whether an application reads the system proxy setting or environment variables. In theory it covers almost every network request, including background services and game clients.

Enabling TUN mode generally requires: running the client with administrator/root privileges, enabling the tun field in the config, and confirming that stack (e.g. gvisor or system) is compatible with your local network environment. Once enabled, the system proxy toggle can stay off, since traffic is already intercepted at a lower level — having both on at the same time usually doesn't conflict, but there's no need to stack them.

tun:
  enable: true
  stack: gvisor
  auto-route: true
  auto-detect-interface: true
When to switch to TUN If your terminal has multiple tools each running their own network logic (certain IDE-bundled package managers, game updaters, etc.), configuring environment variables one by one gets expensive fast. Just enabling TUN mode solves it in one shot, which is far more efficient than bouncing back and forth between browser extensions and environment variables.

Troubleshooting flow summary

When you run into "system proxy is on but not working," work through the following order instead of poking at random settings:

  1. First check Clash's connection panel to see whether the relevant request shows up at all — if it doesn't, traffic never reached Clash in the first place, so check whether the system proxy configuration was actually written correctly.
  2. For browser issues, check proxy-management extensions and built-in network-acceleration features first — these two are the most commonly overlooked.
  3. For terminal issues, first confirm the environment variables actually took effect in the current session, then check whether the specific tool follows environment variables or needs its own config file.
  4. When checking each program individually gets too costly, or when many programs don't follow standard proxy logic, just switch to TUN mode as a fallback instead of adapting each one separately.

System proxy, browser extensions, environment variables, and TUN mode are essentially four independent yet stackable ways of taking over traffic. Figuring out which layer the problem is actually in will get you to a fix far faster than blindly restarting the client.

Download Clash