Why "system proxy is on" doesn't mean "all traffic goes through the proxy"
The "system proxy" toggle in the Clash client essentially modifies the proxy settings in the operating system or desktop environment (Windows WinINet settings, macOS network service proxy, Linux GSettings or environment variables). These settings only take effect for programs that actively read the system proxy configuration — typically browsers and some GUI apps. It isn't a network-layer enforcement mechanism, and any process can simply ignore this setting. That's the root cause behind the common complaint: "the proxy is clearly on, but this one program still isn't going through it."
Command-line tools (curl, wget, git, package managers, etc.) mostly don't read system proxy settings at all — they read environment variables (http_proxy, https_proxy, all_proxy). This means the system proxy being on and the terminal being able to use the proxy are two separate things, and each needs its own troubleshooting approach.
If you need proxying enforced uniformly across every program regardless of whether it reads proxy settings, the only reliable method is TUN mode — it intercepts traffic at the network interface layer, independent of whether the application actively reads proxy configuration. This article covers the trade-offs between the system proxy and TUN mode later on.
Before troubleshooting, confirm one thing first: is Clash actually running, and does it have a usable node? If the core isn't running, or every node in your subscription has failed, no amount of correct proxy configuration will establish a connection. In this situation, check the running logs first to confirm the proxy port is listening correctly.
Troubleshooting steps for a browser not using the proxy
Browsers not proxying usually falls into four categories: the proxy toggle isn't actually applied, the browser has its own independent proxy setting, an extension or security software is intercepting traffic, or DNS isn't going through the proxy causing partial leaks. Work through these in order.
Step 1: Confirm the system proxy toggle status
Open the Clash client's settings page and confirm "System Proxy" is turned on, then check the listening port (usually the HTTP/Mixed port, defaulting to around 7890). Some clients reset this toggle when switching config files, and it can also get reverted to off by the OS after an update or restart.
- Windows: open "Settings → Network & Internet → Proxy" and confirm "Use setup script" or "Manual proxy setup" points to the local address and correct port.
- macOS: open "System Settings → Network → [selected network service] → Details → Proxies" and confirm both Web Proxy (HTTP) and Secure Web Proxy (HTTPS) are checked with the correct port entered.
- Linux (GNOME and similar desktop environments): in "Settings → Network → Network Proxy," confirm it's set to "Manual" rather than "Automatic" or "Off."
Step 2: Rule out the browser's own independent proxy setting
Some browsers (Firefox in particular) don't follow the system proxy by default — they use their own connection settings instead. If Firefox has a proxy manually configured, or "No proxy" selected, it won't use the proxy even if the system proxy is working fine. Check here:
- Firefox: Settings → General → Network Settings → confirm "Use system proxy settings" is selected.
- Chrome / Edge / most Chromium-based browsers: these follow the system proxy by default and usually don't need separate configuration, but enterprise policies or certain extensions can override this — check the browser's proxy settings page to see if it's been locked.
Step 3: Check for interference from extensions or security software
Ad-blocking extensions, enterprise security clients, and some VPN clients can forcibly rewrite the network request path or hijack proxy settings. Try testing in your browser's private/incognito window first (extensions are disabled by default there) — if things work normally, the problem lies with one of your extensions, and you can disable them one at a time to isolate it.
Step 4: Confirm whether DNS requests are also going through the proxy
"The connection works but it's slow" or "some sites work fine while others don't" is often caused by DNS leakage — web traffic goes through the proxy, but domain resolution happens via local DNS, which gets intercepted or interfered with by the local network or ISP beforehand. Technically this isn't the proxy "not working," but the symptoms look similar — also check whether rule mode has DNS hijacking or fake-ip mode enabled.
If you just want to verify the proxy chain itself is working, it's better to check an IP-lookup page and see whether the exit IP changes, rather than testing one specific website first — a specific site behaving oddly might just mean a rule routed it to the direct-connection group, which doesn't mean the proxy has failed overall.
Troubleshooting steps for terminal commands not using the proxy
Whether a terminal tool uses the proxy depends on whether that tool reads proxy environment variables, and whether those variables are correctly set and inherited by the current session. Follow this order.
Step 1: Confirm the environment variables are set
In a macOS / Linux terminal, run:
echo $http_proxy
echo $https_proxy
echo $all_proxy
If the output is empty, the current session has no proxy environment variables set, so terminal commands naturally won't use the proxy. To set them manually (replace the port with your client's actual listening port):
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:7890"
On Windows with PowerShell, the equivalent commands are:
$env:http_proxy="http://127.0.0.1:7890"
$env:https_proxy="http://127.0.0.1:7890"
Step 2: Confirm the variables are written to the correct config file
Variables set temporarily with export only apply to the current terminal session — a newly opened terminal window won't inherit them. For them to persist, write them into your shell's startup config file, such as ~/.zshrc, ~/.bashrc, or ~/.bash_profile (depending on the shell and OS in use), then run source ~/.zshrc or reopen the terminal for the change to take effect.
Step 3: Confirm whether the tool itself actually reads these variables
Different tools follow different conventions:
curl,wget: readhttp_proxy/https_proxyby default; case is usually insensitive but lowercase is recommended for consistency.git: doesn't automatically forward system environment variables — you need to configuregit config --global http.proxyandhttps.proxyseparately.- Package managers (npm, pip, apt, etc.): each has its own proxy configuration option, and environment variables aren't always recognized — you usually need to declare the proxy address in that tool's own config file.
- Docker, Docker Compose: processes inside a container don't share the host's environment variables by default — you need to explicitly pass proxy variables into the Docker config or
docker-compose.yml, or configure a proxy separately for the Docker daemon.
Step 4: Verify the proxy chain with a minimal command
To rule out interference from a tool's own logic, test the proxy port directly with curl:
curl -x http://127.0.0.1:7890 -I https://www.example.com
If this command returns response headers normally, the proxy port itself is working fine, and the problem is that the specific tool isn't correctly reading the proxy configuration. If even this command times out or errors, the problem lies with the Clash client or the node itself — go back to the client and check node connectivity and the listening port.
It's worth making "manually specify the proxy with curl's -x flag" your first verification step for any terminal-related issue — it quickly narrows the problem down to either "the proxy port" or "the specific tool's configuration," instead of going in circles inside a tool's own complex settings.
System proxy toggle vs. TUN mode: which to choose
The system proxy and TUN mode are two mechanisms with completely different coverage — it's worth clarifying your actual use case before choosing between them.
Characteristics of the system proxy toggle
The system proxy only modifies the proxy configuration read by the OS or browser. Its advantages are low overhead, flexible switching, and no intrusion into the system network stack. Its downside is incomplete coverage — any program that doesn't actively read the system proxy setting (some command-line tools, games, certain background services) won't be covered, and needs extra manual configuration via environment variables or in-app proxy options.
Characteristics of TUN mode
TUN mode creates a virtual network interface on the system, and the Clash core intercepts all traffic passing through that interface, regardless of whether the application actively configured a proxy. This means traffic from command-line tools, background services, games, and other things that normally "don't follow the system proxy" gets handled uniformly too — much closer to true global proxying. The trade-off is more complex configuration (usually requiring process mode, routing table adjustments, or firewall rules), and some systems require admin/root privileges to create a virtual network adapter.
Recommendations for choosing between the two
- If you only need browsers and common desktop apps to use the proxy: the system proxy toggle is simplest to configure, and issues are easier to trace back to a specific piece of software.
- If you need command-line tools, scripted tasks, and background services to consistently use the proxy without configuring environment variables one by one: TUN mode is the better choice, covering most cases in one shot.
- If you also need fine-grained routing control (some programs direct, others proxied): TUN mode combined with process rules or IP-range rules is far less tedious than configuring a proxy separately for each tool, though it takes time to understand how rule configuration works.
- When connection issues occur, first confirm whether you're currently using the system proxy or TUN mode, then troubleshoot accordingly — the symptoms and checks differ between the two, and mixing them up tends to lead you astray.
If some traffic still bypasses the proxy after enabling TUN mode, it's usually caused by a conflict in the routing table or firewall rules. Try temporarily disabling other VPN or network-acceleration tools and retest, to rule out multiple network-intercepting tools conflicting with each other.
Common false alarms and the right troubleshooting mindset
Around system proxy issues, several patterns are frequently mistaken for "the proxy isn't working," when the actual cause has nothing to do with the proxy configuration itself:
- A rule sent a site through direct connection: if the config file has a direct-connection rule for a specific domain or IP range, that site bypassing the proxy is expected behavior, not a fault.
- The node itself has connection issues: the proxy configuration is correct but the node has failed — this also looks like "the page won't load," so test the node's latency and connectivity separately in the client first.
- Stale DNS cache: after switching proxy or node, the local DNS cache may still point to old resolution results — flush the system DNS cache or restart networking services before troubleshooting further.
- Multiple proxy tools running at once: if another proxy app or VPN is running simultaneously, the system proxy setting may get overridden by whichever tool started most recently — confirm only one tool is actively modifying network settings before troubleshooting.
The overall approach can be summarized as: first confirm Clash itself is running normally with a usable node, then confirm the system proxy toggle or environment variables are correctly configured, and finally confirm whether the specific application actually follows that configuration. Verifying layer by layer in this order avoids getting stuck adjusting the wrong layer repeatedly without ever finding the root cause.