First, distinguish system proxy, app proxy, and rule-based routing

Turning on the system proxy only tells the operating system to save proxy settings; it does not mean every process will use them. A browser may follow the system settings, or an extension or separate configuration may override them. Command-line tools typically need environment variables or explicit proxy options. Once a connection reaches the Clash core, its final route depends on the current mode, rules, and proxy group.

So an unchanged public IP does not, by itself, mean the system proxy is broken. The connection may have reached the core but matched DIRECT, or the app may have bypassed the proxy entirely. Check both the app's settings and the client's connection log; don't rely only on whether the page loads.

On Clash or mihomo cores that support these fields, the snippet below provides HTTP and SOCKS proxy listeners on the local machine only. Merge it into an existing configuration; it contains no nodes or rules and is not a complete subscription.

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

Step 1: Check the listener and test an explicit proxy request

Bypass the system proxy toggle and specify the proxy directly in a command. If that also fails, check the listening port, whether the core is running, and the node connection before changing browser settings.

Check whether port 7890 is listening

Run this command in Windows PowerShell. The OwningProcess value is the process ID. Look it up on Task Manager's Details tab to avoid mistaking another app's port for Clash's.

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

On macOS, use lsof; on Linux, use ss. If there's no output, first check whether the actual port is different and whether the configuration loaded successfully.

# macOS
lsof -nP -iTCP:7890 -sTCP:LISTEN

# Linux
ss -lntp 'sport = :7890'

Use curl to specify an HTTP proxy explicitly

On Windows, use curl.exe to avoid conflicts with a same-named alias in some PowerShell environments. On macOS and Linux, use curl. The --noproxy "" option prevents an existing bypass list from affecting this test.

curl.exe --proxy http://127.0.0.1:7890 --noproxy "" --connect-timeout 10 --max-time 30 -v https://example.com/

First check whether the connection reaches 127.0.0.1:7890, then whether the HTTPS CONNECT tunnel is established, and only then check the target site's response. The example domain is for connectivity testing; to diagnose the actual issue, use the same URL that's failing.

ResultCheck first
Connection to local port 7890 is refusedCheck that the core is running, the port matches, and the listener address is reachable.
Local listener connects, but the target connection times outCheck the target, rule, proxy group, and node route in the client log.
Request succeeds, but the browser still failsCheck the browser's proxy source, extensions, bypass list, and existing connections.
Explicit proxy option works, but a regular terminal command failsCheck whether environment variables are set, whether the program supports them, and whether a tool-specific setting overrides them.

A successful CONNECT only confirms that the proxy listener accepted the tunnel request; it doesn't prove that traffic used a particular remote node. Check the rule and connection route in the client details to determine the final path.

Step 2: Check the browser's proxy settings, source by source

Check the actual address in the operating system first

In Windows 11, go to Settings → Network & internet → Proxy and check the manual proxy address and port. On macOS, go to System Settings → Network → the active network service → Details → Proxies. Labels may vary slightly between OS versions. Make sure you check the network service currently in use, not a disconnected Wi-Fi network or adapter.

Rule out extensions and browser-specific settings

In standard desktop setups, Chrome and Edge generally use the system proxy, but proxy-switching extensions, launch flags, and enterprise policies can override it. Temporarily disable proxy-related extensions, fully quit and reopen the browser, then test the same URL. Incognito mode doesn't necessarily disable all extensions; they may be allowed to run there.

In Firefox, check the proxy source under Settings → General → Network Settings → Settings. To follow the operating system's settings, select Use system proxy settings. If you select Manual proxy configuration, check the address, port, and No proxy for list separately.

On company-managed devices, check the browser's management status too. Use chrome://policy in Chrome or edge://policy in Edge to see which policies are active. If a managed policy restricts changes, ask your administrator instead of repeatedly overriding the settings.

Check the bypass list and reused connections

Browsers and operating systems often bypass proxies for local addresses, intranet domains, or specific subnets. Testing with localhost, a router admin page, or a company intranet address won't tell you whether the proxy works for public sites. Existing long-lived connections may also remain in use after you change settings. For a reliable retest, close the relevant tabs and fully quit and relaunch the browser rather than repeatedly refreshing the same page.

Step 3: Set http_proxy and HTTPS_PROXY separately in the terminal

Opening the system proxy in the client doesn't automatically set environment variables for every command in a terminal. Set them temporarily in the current session first, and make them persistent only after confirming they work. For an HTTP proxy listener, the proxy URL is usually still http://127.0.0.1:7890, even when the destination is an HTTPS site. Don't change it to https:// just because the variable name contains HTTPS.

macOS and Linux: Set variables temporarily 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 --connect-timeout 10 --max-time 30 -v https://example.com/

# Remove these settings when testing is complete
unset http_proxy https_proxy no_proxy

For HTTP proxy variables, curl accepts only lowercase http_proxy; support for uppercase names varies between programs. Also check for uppercase variables, ALL_PROXY, and tool-specific settings so another source doesn't keep affecting requests after you remove one set of variables.

Windows PowerShell: Set environment variables for the current process

$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 --connect-timeout 10 --max-time 30 -v https://example.com/

# Remove these settings when testing is complete
Remove-Item Env:HTTP_PROXY, Env:HTTPS_PROXY, Env:NO_PROXY

These settings apply only to the current PowerShell process and any child processes started afterward. They won't change an IDE, terminal, or background service that's already running. If a variable already had a value, save it first and restore it after testing rather than deleting it. After changing variables persistently through the system settings, you'll usually need to restart the affected apps for them to inherit the new values.

Step 4: Check Git, WSL, and tool-specific proxy settings

If curl works but a particular tool doesn't, don't assume the node is down. Git, package managers, and runtimes may have their own proxy settings or handle environment variables through different networking libraries. For Git, start by checking all configured settings and where they come from:

git config --show-origin --get-regexp '.*proxy.*'

Settings may come from the system, user, or current repository configuration. If a setting is outdated, change it at the relevant scope rather than clearing every level. To specify a proxy for just one command, run:

git -c http.proxy=http://127.0.0.1:7890 ls-remote https://github.com/git/git.git HEAD

Step 5: Once traffic reaches the core, check the rule and route

Find the request in the client's connection list or runtime log using the target domain and test time. Note the destination, matched rule, selected proxy group, and actual route. Client interfaces use different labels, but these details reveal where traffic went more clearly than an “enabled” status.

  1. If you see DIRECT, first check whether a direct-connection rule matched or the selected proxy group is set to direct.
  2. If the request reaches the expected proxy group but times out, check the node, server, and connection from your machine to the node.
  3. If there's no matching entry, first check the log level, filters, and whether the request was actually sent. Then check the app's proxy entry point again.

Temporarily setting log-level: debug can provide more clues; restore info after reproducing the issue. Logs may contain domains, internal addresses, and subscription-related information, so redact them before sharing. Don't “fix” proxy issues by disabling TLS certificate verification; troubleshoot certificate errors by checking the certificate chain, system clock, and network interception separately.

When should you consider TUN mode?

Consider TUN when an app doesn't support proxy settings or you need to capture more network traffic. A system proxy relies mainly on apps using the proxy listener directly; TUN captures traffic through a virtual network interface and routing, so its coverage is different. mihomo, the successor project to Clash Meta, supports related features, but availability depends on the client's integration, system permissions, and runtime environment. Not every client called Clash uses the same implementation.

In a mihomo environment, the following illustrates how the fields relate; it's not a universal configuration for every device. Some clients generate these fields from UI options. Check the final active configuration first to avoid conflicts between UI toggles and manually entered settings.

tun:
  enable: true
  stack: mixed
  auto-route: true
  auto-detect-interface: true

Narrow down the cause without changing multiple settings at once

The shortest troubleshooting path is: check the listening port → test with an explicitly specified proxy → check the browser's proxy source → check terminal environment variables → check rules and routes in the client. Consider TUN only if the app genuinely can't connect through a standard proxy.

For each retest, keep four details: OS and client name, actual listening port, full command used, and connection log from the same time. If the explicit proxy works but the browser fails, keep investigating the browser. If a terminal command works with proxy options but fails without them, check environment variables and tool settings. This turns “system proxy not working” into a testable issue instead of a reason to reinstall the client repeatedly.

For field definitions, see Clash Config Fields. To import a configuration and choose a proxy mode for the first time, follow the Getting Started guide in order.