How can you tell whether a VPN is really working? You cannot rely only on the “Connected” status in the client. That status usually means the client completed its handshake, a proxy port is listening, or a virtual network interface appeared in the system. It does not necessarily prove that requests from your browser, command-line tools, and other apps are using the intended route. A reliable check combines your public IP, the destination of DNS queries, and the actual path used by each app.

The most important verification principle is comparison. Record the network state before connecting, then connect to the route and repeat exactly the same requests. Looking only at a single result after connecting can make your original local exit, browser cache, or secure DNS service look like the VPN result. The workflow below is independent of the client brand and applies to common setups including system proxies, TUN mode, native VPN configurations, and browser extensions.

What to Check: An Icon, Handshake, and Actual Traffic Are Different Things

A connection can be divided into several stages: loading the configuration, completing the protocol handshake, taking over system traffic, and sending requests from an app. A subscription link is only the entry point for distributing configuration; a successful import merely shows that the client read the node information. After Shadowsocks, VMess, Trojan, VLESS, Hysteria2, or TUIC completes its handshake, the client still has to pass traffic through the system proxy, a virtual network adapter, or an in-app proxy.

Signal What it can prove What it cannot prove by itself
The client shows “Connected” The configuration has started and the route handshake has usually completed Every app is using the route
The system shows a VPN or virtual adapter indicator A system network interface has been created The default route and DNS have switched as expected
The public IP has changed The current test request used a different exit Other apps and DNS requests use the same path
The DNS resolver has changed The current lookup used a different resolver The web request itself definitely used the intended route
The target app request succeeded The app has a usable path under the current rules Background processes and other apps are also being routed

The accurate conclusion is therefore not “the client light is on,” but “a new request from the intended app left through the expected exit, and domain resolution matches the current configuration.” With split tunneling enabled, some requests remaining direct may be normal. What matters is whether the result follows the rules, not whether every request shows the same exit.

Record a Baseline and Compare the Public IP

Your public IP is the most direct first check. Disconnect, then use a trusted IP lookup page to record the public address, network operator, and approximate region. Connect to the intended route and refresh the result. If the address and network ownership change, the lookup request did use a different public exit.

  • ✅ Disconnect from the route, disable browser extensions that may automatically take over traffic, and record the current exit details.
  • ✅ Connect to the intended route, wait for the client to show that the handshake is complete, then run the lookup in a new browser tab.
  • ✅ Compare the public address, autonomous system ownership, and region—not just the city shown on a map.
  • ✅ Check IPv4 and IPv6 separately; dual-stack networks may choose different paths for the two types of requests.
  • ✅ Recheck with another app that is expected to use the route, so a browser-specific proxy setting is not mistaken for a system-wide result.

Region labels are only supporting evidence. An IP database may place the same address range at a data center’s registered location, the network operator’s location, or a nearby city, so a different city does not necessarily mean the route has failed. More useful signals are whether the public address changed, whether the network ownership matches the node type, and whether multiple new requests continue to use the expected exit.

If the address is exactly the same before and after connecting, do not start switching nodes repeatedly. Check whether the current mode only opened a local proxy port without enabling the system proxy or TUN. Also confirm that the lookup page was not classified as direct traffic by the split-tunneling rules. A browser extension may override system settings, causing the browser and other apps to show opposite results.

Domain Resolution: Checking the DNS Resolver and Leaks

DNS converts domain names into addresses that can be reached. If web traffic uses the route but DNS queries still go to the local network resolver, the domains you access may be sent along a different path. This is commonly called a DNS leak. The key question is not whether the DNS region exactly matches the exit region, but whether the resolver matches the setup defined in the client, system, or browser.

Modern browsers may enable encrypted DNS and use a resolver selected directly in the browser. Android Private DNS, system network settings, and a client’s built-in DNS can also override one another. Seeing a third-party DNS network in the results does not automatically mean there is a leak. First identify who is handling resolution, then determine whether that path is expected.

Every desktop platform lets you inspect the current resolver configuration. The commands below show system state; they do not directly prove whether a browser bypasses system DNS, but they can help identify where the configuration comes from:

Windows
ipconfig /all

macOS
scutil --dns

Linux
resolvectl status

Windows output shows the DNS servers used by active network interfaces. macOS lists resolvers for different scopes. On Linux systems using systemd-resolved, you can inspect DNS and default-route status for each interface. If the client uses TUN and takes over DNS, related clues are usually available on the virtual interface or in the client configuration.

You also need to check secure DNS settings in the browser separately. If the browser is forced to use a custom resolver, the server shown by system commands may not handle web lookups at all. Conversely, some clients intercept system DNS and forward it through the tunnel; in that case, the address visible locally is only the receiving endpoint, while the final recursive resolver may be on another network.

DNS conclusion: A mismatch between the exit region and DNS region is not enough to prove a leak. Correct the DNS takeover, browser secure DNS, or split-tunneling configuration only when queries bypass the intended tunnel or proxy policy and are handled by the local network or an unexpected resolver.

Per-App Requests: Find Out What Is Connecting Directly

An IP lookup page only proves that the app making that lookup used the route. A working browser does not mean that your terminal, download tool, game, or desktop communications app uses the same path. The safest approach is to run equivalent requests in each app and relate the results to the access mode.

A system proxy usually affects software that actively reads the system proxy settings. Some command-line tools, games, and apps with their own network stacks ignore them. TUN mode takes over a broader range of IP traffic through a virtual network interface, but it can still be affected by excluded routes, app bypass rules, and direct LAN rules. Browser extensions have a narrower scope and generally handle only proxy-capable requests inside that browser.

  1. First check the exit in your browser and record the result.
  2. Then use a command-line network tool to request the same type of exit lookup endpoint and compare the network ownership.
  3. Open the desktop or mobile app you need to verify and trigger a new request instead of inspecting cached content.
  4. Check the client connection log or active connection list for the target domain, target address, or corresponding process.
  5. Switch briefly to global mode for comparison. If global mode works but split tunneling does not, the issue is usually in rule matching.

Client logs are better than “can the webpage open?” for locating split-tunneling problems. If a request is marked direct, check domain rules, IP rules, process rules, and rule priority. A domain may resolve to a content delivery network address; if matching actually occurs at the IP stage while only a domain rule was written, the resulting path may differ from what you expected.

Also distinguish connection testing from service availability. A successful route handshake and a changed exit show that the transport path basically works. If the target service still returns an error, the cause may be the account region, cache, browser storage, time settings, or the service’s own policy. Changing the proxy port repeatedly usually will not fix an application-layer problem.

Common False Positives and Fixes

The client starts, but system traffic takeover is not enabled

Many proxy clients let you control “start the core” and “set system proxy” separately. The former only listens on a local proxy port and suits apps where you enter the proxy manually; the latter changes the system proxy settings. If you need to cover more software that does not read the system proxy, evaluate TUN mode when supported by the client and check that permission to use the virtual adapter has been granted.

Split-tunneling rules classify the test target as direct

Rule mode chooses a path based on domains, addresses, processes, or rule sets. If an IP lookup site matches a direct rule, it will show the local exit even though other targets may already use the route. Temporarily switch to global mode for comparison. After confirming that the route itself works, return to rule mode and correct the rules.

IPv4 uses the route while IPv6 remains direct

A dual-stack network selects a protocol family based on the domain response and system routing. If the client takes over only IPv4 while the app prefers IPv6, the lookup may expose the local IPv6 exit. Do not blindly disable system features; first confirm whether the client supports the relevant traffic, then adjust TUN, routing, or DNS response policies.

The browser and system use different DNS resolvers

Browser secure DNS can bypass system resolver settings, while system Private DNS may also take priority over the client configuration. Choose one controlled setup: let the browser handle encrypted resolution, or let the client handle it consistently inside the tunnel. When several layers are enabled at once, the result may work but troubleshooting becomes harder.

Existing connections did not switch with the route

An app may reuse existing connections, while connection pools and background processes may keep using the old path. After switching nodes, make the test app establish a new connection. Quitting the app, reopening the page, or clearing related connection state is more effective at removing old-session interference than clicking refresh repeatedly.

  • ✅ The browser changes but other apps do not: check the system proxy’s coverage, or use an appropriate TUN setup.
  • ✅ Global mode changes but rule mode does not: check direct rules, rule order, and process matching.
  • ✅ The IP changes but DNS still uses the local network: check client DNS takeover and browser secure DNS.
  • ✅ IPv4 changes but IPv6 does not: check dual-stack routing and the client’s protocol-family support.
  • ✅ All exits are correct but the target service fails: investigate the account, cache, region detection, and application-layer errors.

Platform Differences: Why the Same Configuration Behaves Differently

On Windows, the system proxy and routing table are separate mechanisms. A browser may read the system proxy while a command-line program may not; TUN mode depends on a virtual adapter and routes. Use route print to inspect the default route and whether the virtual interface participates in forwarding, then combine that with client logs to identify the specific request.

On macOS, system proxy settings are stored per network service, while clients based on Network Extension can create system-level tunnels. If multiple network extensions are installed on the same device, avoid enabling conflicting takeover methods at the same time. Use scutil --proxy to inspect system proxy status and scutil --dns to check resolver scopes.

On iOS, the VPN indicator in the status bar only shows that the configuration is active. You still need to verify the exit and real service requests to confirm that browser, in-app, and DNS traffic behave as expected. Some apps may use cached content, so trigger a new load after switching routes. Organization-managed per-app VPN and a standard personal configuration also have different takeover scopes.

Android includes VPN services, always-on connections, Private DNS, and app exclusion lists. An excluded app remains direct; if Private DNS is enabled independently, its resolution path may also differ from the client’s. During verification, check the client’s per-app settings and the system network settings instead of relying only on the key or VPN icon.

Linux can run a desktop network manager, proxy environment variables, and TUN routes at the same time. Whether a terminal tool uses a proxy depends on the tool’s own settings and environment variables; system-level routes affect a wider range of traffic. Use ip route to inspect routes and resolvectl status to inspect resolvers, then compare them with connection records for the target process.

Full Review: Narrow the Problem Down in a Fixed Order

When results conflict, do not change the protocol, node, DNS, and split-tunneling rules all at once. Change one variable at a time so you can identify which setting actually affects the result. First verify basic route connectivity, then system takeover, and finally app rules and DNS.

  1. Disconnect and record the baseline state of the browser, command line, and system DNS.
  2. Connect to the route and confirm that the client has completed its handshake without persistent errors.
  3. Create a new browser request and compare the public IP and network ownership.
  4. Check whether IPv4, IPv6, and DNS match the current takeover setup.
  5. Send new requests from each app that should use the route and review the client logs.
  6. If app results differ, check the system proxy, TUN, app exclusions, and split-tunneling rules in that order.
  7. Restore your everyday rules and test again to ensure a temporary global setting did not hide the problem.
Final verdict: A VPN is confirmed to work for an app only when new requests from that app use the expected exit, the DNS path matches the configuration, and the split-tunneling result follows the rules. Seeing only “Connected” confirms at most that the client has started; it does not replace path verification.