Clash System Proxy Not Working? Fix Browser and Terminal Issues
Troubleshoot a Clash system proxy that isn't working in your browser or terminal. Check extensions, PAC settings, bypass lists, http_proxy variables, and when to use TUN mode.
First, determine whether traffic reaches the client or fails after it gets there
“System proxy enabled” only means the client attempted to change the operating system's proxy settings. It doesn't mean every app will use them. A browser may be controlled by an extension, while terminal tools may rely on environment variables. Even if a request reaches Clash, a rule may route it to DIRECT, or a node connection failure may prevent it from completing.
This guide focuses on desktop versions of Windows, macOS, and Linux. Clash is a common name for the proxy core and its related client ecosystem. Clash Meta was later renamed mihomo; the client determines where settings appear, not the core's name. Android and iOS use VPN-based traffic routing rather than desktop system proxy settings, so the steps here don't apply directly to their system settings.
- Confirm the configuration is loaded in the client, set the outbound mode to “Rule,” and note which node the current policy group has selected.
- Open the client’s “Connections” page and check “Logs” as well. If needed, temporarily set the log level to
info. - Send a new request to a specific domain, then check the connection time, destination, matched rule, and outbound route.
- No connection entry? Check how the app connects first. An entry routed to DIRECT points to a rule issue. If there’s an entry but the connection times out, check the node, DNS, and remote service.
Local proxy endpoint: check the address, port, and core status
The examples below use 127.0.0.1:7890. Port 7890 is a common setting, not a universal default. Check the actual value under “Port” or “Mixed Port” in the client’s “Settings,” then use that port in the commands. Don’t mistake the controller port or dashboard address for the proxy port.
| Configuration field | Purpose | What to check |
|---|---|---|
mixed-port | Accepts HTTP and SOCKS proxy requests on the same port | Can be used as the HTTP proxy endpoint in the tests below |
port | HTTP proxy listening port | Don’t send it a SOCKS handshake |
socks-port | SOCKS proxy listening port | Use a SOCKS proxy URL for testing |
external-controller | Core controller API | Not a browser proxy endpoint |
Windows: check the listening port and owning process
netstat -ano | findstr :7890
Look for a line with a local address of 127.0.0.1:7890 or the corresponding listening address, and a status of LISTENING. Note the PID in the last column, then check the process under “Details” in Task Manager. If another client is using the port, the current client may open successfully while its core fails to bind to the port.
macOS and Linux: check for a TCP listener
lsof -nP -iTCP:7890 -sTCP:LISTEN
If lsof isn't installed, Linux users can run ss -lntp to list listening sockets. If nothing is listening, check the core startup logs, configuration parsing errors, and port conflicts before changing browser settings. For local use, you usually don't need to enable “Allow LAN” or bind to every network interface.
Browser checks: system settings, extensions, PAC, and bypass lists
Check the proxy address saved by the operating system
- Windows 11: Go to “Settings” → “Network & internet” → “Proxy.” Check the server and port under “Manual proxy setup,” and make sure “Use setup script” doesn't still point to an old PAC URL.
- macOS 13 and later: Go to “System Settings” → “Network” → the active network service → “Details” → “Proxies.” Check “Web Proxy (HTTP),” “Secure Web Proxy (HTTPS),” and “Automatic Proxy Configuration.” Check the relevant service again after switching between Wi-Fi and Ethernet.
- GNOME desktop: Proxy settings are usually under “Settings” → “Network” → “Network Proxy.” System proxy settings vary across desktop environments, and apps may not use the same configuration.
An HTTP proxy address is usually entered as 127.0.0.1, with the port entered separately as 7890. HTTPS sites use a CONNECT tunnel through the HTTP proxy; that doesn't mean the proxy server address must start with https://. Whether the system settings require a protocol prefix depends on the interface.
Chrome and Edge: check extensions and policy overrides
In Chrome, open chrome://settings/system; in Edge, open edge://settings/system, then go to the system proxy settings. Next, check chrome://extensions or edge://extensions, temporarily disable proxy-switching extensions, and fully quit and relaunch the browser.
Incognito mode isn't a reliable isolation test: some extensions are allowed to run in incognito, and system proxy settings and enterprise policies still apply. On managed devices, also check chrome://policy or edge://policy. If an organization policy locks the proxy settings, contact your administrator instead of repeatedly overriding them.
Firefox: check its separate network settings
In Firefox, go to “Settings” → “General” → scroll down to “Network Settings” → “Settings.” Select “Use system proxy settings” to use the system configuration. If “Manual proxy configuration” is selected, check the HTTP proxy, port, and whether the same proxy is used for HTTPS. “No proxy” and “Auto-detect proxy settings for this network” don't read the manually configured proxy set by the client.
PAC and bypass lists: domain-based routing may happen before traffic reaches the client
A PAC script can return DIRECT or a proxy address for each URL. If it returns DIRECT for the target domain, the request never reaches Clash, so local rules can't handle it. Keep a copy of the original settings, temporarily use just one proxy entry point—for example, turn off the automatic script and set a manual HTTP proxy—and test the same destination again.
Also check Windows proxy exceptions, macOS’s “Bypass proxy settings for these Hosts & Domains,” and Firefox’s “No proxy for” list. localhost, 127.0.0.1, and internal domains are often bypassed, so accessing a local page doesn't show whether external traffic uses the proxy. Send a new request and check whether the client logs the domain; browser cache can otherwise be misleading.
Terminal checks: specify the proxy first, then inspect environment variables
A terminal is a process environment, not a browser. curl, Git, package managers, and script runtimes each handle proxy settings differently; enabling the desktop system proxy doesn't guarantee these tools will use it. Start by sending a single request directly to the local proxy endpoint to avoid most environment variable and app configuration issues.
Run a minimal test with curl
Run the command below on macOS or Linux. In Windows PowerShell, use the same arguments but call curl.exe to avoid the curl alias in Windows PowerShell 5.1, which points to a different command.
curl -v --noproxy "" --proxy http://127.0.0.1:7890 --connect-timeout 10 --max-time 20 https://example.com/
--noproxy "" clears the bypass list for this request. --connect-timeout 10 and --max-time 20 set the connection timeout and total request timeout, in seconds. For an HTTPS destination, the logs will typically show a connection to the local proxy followed by the CONNECT tunnel setup. 200 Connection established confirms only that the tunnel was created; it doesn't guarantee the subsequent TLS handshake or web request will succeed.
Connection refused: first check the local port, listening address, and whether the core is running.- Connected to the local port, but CONNECT or the subsequent request times out: check the policy group, node, and destination against the client logs.
- Explicit proxy works, but plain
curlfails: focus on environment variables and the tool’s own settings. - Certificate error: check the system clock, certificate trust chain, and managed network settings. Disabling certificate verification is not a long-term fix.
macOS and Linux: set variables in the current shell
export http_proxy=http://127.0.0.1:7890
export https_proxy=http://127.0.0.1:7890
export no_proxy=localhost,127.0.0.1,::1
curl -v --connect-timeout 10 --max-time 20 https://example.com/
https_proxy specifies the proxy to use for HTTPS destinations; its value can still use http://. curl accepts only lowercase http_proxy for HTTP proxy settings, not uppercase HTTP_PROXY. Other tools also differ in their case handling, so don't assume every program behaves the same way.
These export commands affect only the current shell and its child processes; they don't change programs that are already running. Once testing succeeds, add the variables to the appropriate startup file, such as ~/.zshrc or ~/.bashrc. An IDE's integrated terminal may inherit the environment from when the IDE started, so restart the relevant processes.
Windows PowerShell: set environment variables for the current session
$env:http_proxy = "http://127.0.0.1:7890"
$env:https_proxy = "http://127.0.0.1:7890"
$env:no_proxy = "localhost,127.0.0.1,::1"
curl.exe -v --connect-timeout 10 --max-time 20 https://example.com/
These assignments won't persist after you close the current window. Windows desktop proxy settings, WinHTTP proxy settings, and process environment variables are separate entry points. The output of netsh winhttp show proxy doesn't tell you how browsers or curl behave. Check this path only if you know the target program uses WinHTTP.
Remove stale variables and app-level proxy settings
On macOS or Linux, run env | grep -i proxy; in PowerShell, run Get-ChildItem Env:*proxy*. Look for ALL_PROXY pointing to an old port, uppercase variables, and an overly broad NO_PROXY. For curl, a matching protocol-specific proxy variable usually takes precedence over ALL_PROXY, while the bypass list may send requests directly.
If only Git fails, use git config --show-origin --get-regexp '.*proxy.*' to see where its settings come from. Package managers may have their own proxy settings too, so check the tool in question instead of changing every global setting. When you're done testing, remove common proxy variables from the current Unix shell session with:
unset http_proxy https_proxy all_proxy no_proxy
unset HTTP_PROXY HTTPS_PROXY ALL_PROXY NO_PROXY
Requests reach Clash: check rules, DNS, and the outbound route
If both browser and curl connections appear in the client’s connection list, traffic is reaching the client. Changing the system proxy again is unlikely to help. Open the relevant connection details and check the destination domain, matched rule, policy group, and final node in that order.
- Rule matches DIRECT: Check whether this is expected. Rules are usually evaluated from top to bottom, so an earlier direct-connection rule may match before a later proxy rule. Also check that rule sets loaded successfully.
- Policy group selects DIRECT: Even if a proxy policy group matched, its manually selected option may still be DIRECT. Check the active selection, not just the group name.
- Node connection fails: Switch to another node in the same group and retry the same destination. A successful latency test only means its test destination is reachable; it doesn't guarantee every website will be.
- DNS error: Use the logs to determine whether the destination domain failed to resolve, the proxy server’s domain failed to resolve, or the connection to the DNS server failed. Don't change DNS, rules, and nodes all at once before identifying the cause.
To check whether rules are the issue, briefly switch to “Global” mode and explicitly select a proxy node, then run a single test and switch back to “Rule.” Global mode only changes the outbound route for traffic that reaches the core; it doesn't force apps that aren't using the proxy into the client.
When to use TUN mode: for apps that ignore proxy settings
Consider TUN mode when browser traffic and explicit proxy tests work, but some apps don't use system proxy settings or environment variables. TUN routes traffic through a virtual network interface and can handle a wider range of TCP and UDP traffic. Actual coverage depends on routes, exclusions, core configuration, and platform permissions; enabling it doesn't guarantee every connection will use a remote node.
- Windows: Install the service mode or grant administrator privileges as required by the client, then enable TUN and confirm the virtual network interface and routes were created successfully.
- macOS: Install the helper service and grant the required network permissions as instructed by the client. If startup fails, check permissions and route logs first.
- Linux: Confirm the TUN device is available and grant the network management permissions required by the client's deployment method. Containers and restricted environments may not be able to create a virtual network interface.
Common TUN settings in mihomo include enable, stack, auto-route, and dns-hijack, but different versions and clients may generate the configuration through their interface. Prefer the controls provided by your current client; don't replace an existing subscription configuration with a complete setup from another platform.
When troubleshooting TUN, first quit other VPNs or similar clients that take over routing, then test DNS, websites, terminal tools, and local network services in order. Corporate VPNs, virtual machine adapters, and container networks may conflict with automatic routing. If local services become unreachable, check excluded subnets and routes rather than blindly removing every exception.
If only a few tools such as curl or Git need a proxy, explicit options or environment variables are usually easier to troubleshoot. Use TUN when you need to cover apps that don't support proxy settings. If enabling TUN immediately cuts off network access, turn it off to restore connectivity, then check permissions, DNS, and route logs.
Retest checklist: verify three routes against the same destination
| Test result | Check first | Next step |
|---|---|---|
| Explicit curl fails with connection refused | Local listening endpoint | Check the actual port, process, and core startup logs |
| Explicit curl works, but the browser has no connection entry | Browser proxy source | Check extensions, PAC, bypass lists, and separate network settings |
| Browser works, but regular terminal requests fail | Terminal environment and app settings | Check proxy variables, bypass lists, and tool settings |
| Both show connection entries, but the destination fails | Rules and remote outbound connection | Check DIRECT, policy group, node, and DNS logs |
| Failure occurs only with TUN enabled | Permissions, routes, and network conflicts | Restore the previous mode, then check the virtual interface and DNS one at a time |
Choose one destination domain and test it in this order: curl with an explicit proxy, the browser, then a terminal request without explicit proxy options. For each test, record whether the client received the connection, which rule matched, and which outbound route was used. Once all three paths are confirmed, restore the PAC, extensions, or TUN settings you need, and return the temporary log level to its usual setting.