A green Connected light in the client window doesn't mean traffic is actually leaving through an international route. To confirm the VPN is really working, look at three things separately: whether the exit IP has changed to the node's location, who resolves your DNS queries, and whether the app you're using is covered by the rules. The three steps below give you copy-and-paste checks, followed by the typical cases where the client connects but traffic doesn't follow.
Connecting, capturing and taking effect are three different things
Many people treat these three steps as one, which leaves them with nowhere to start when something goes wrong. In fact they can be independent of each other:
- Tunnel established: the client and the node complete a handshake. Shadowsocks, VMess, Trojan and VLESS usually run over TCP or WebSocket-style transports; Hysteria2 and TUIC are built on QUIC, which sits on UDP. A successful handshake only means that link is up.
- Traffic captured: the client hands local traffic to the tunnel. TUN mode captures all IP traffic; system proxy mode only affects apps that read proxy settings.
- Exit in effect: the destination site sees the node's address as the source, not the address assigned by your local ISP.
When the three come apart, the usual illusion is "the client looks fine, but pages still load with local results". The client isn't lying — the capture scope or the routing rules simply don't cover the target you tested.
Step 1: check the exit IP
Checking once before and once after connecting is the most direct way to judge. Open any IP lookup page in a browser to see the address and its location; the command line is better for before-and-after comparison because the output is clean and easy to record.
# Before connecting: record a baseline
curl -s https://api.ipify.org; echo
# After connecting: check again
curl -s https://api.ipify.org; echo
# Also check the exit region
curl -s https://www.cloudflare.com/cdn-cgi/trace | grep -E '^(ip|loc)='
A normal result is two different addresses, with the second one in the same region as the node you picked. If both are identical, first check whether the routing rules classify that lookup domain as direct, then check whether the current capture mode is system proxy.
IPv6 and WebRTC are the two usual leaks
Most tunnels only capture IPv4 by default. If your local network has native IPv6, sites that support IPv6 are reached straight from your local address while the IPv4 check still looks perfectly normal. Query the IPv6 exit on its own: curl -6 -s https://api64.ipify.org — if it returns your local address, IPv6 isn't being captured.
Browsers have a separate channel too: WebRTC can obtain the local address without going through the proxy. Compare against a browser with no extensions installed, or restrict WebRTC in the browser settings, to tell whether that's where the problem lies.
Command-line tools don't read the system proxy. curl only goes through the proxy if you add -x explicitly or set the http_proxy / https_proxy environment variables. So in system proxy mode, a terminal address that differs from the browser's is expected behaviour; after switching to TUN mode the two should match.
Step 2: check who resolves DNS
DNS turns domain names into addresses. If traffic goes through the tunnel but resolution is still handled by your local ISP, two things follow: your browsing intent is exposed to the local resolver, and results come back based on your local position, so you get a nearby node and the expectation of having switched abroad falls flat.
There are three ways to check:
- An online DNS leak test page lists the resolvers actually used for the lookup — good for a quick glance.
- On Windows use
nslookup example.com; on macOS and Linux usedig example.comand look at which server appears in the SERVER section. - On macOS you can also run
scutil --dnsto see the order of the system resolvers and which one is used by default.
The test isn't "did a local DNS show up" but "who resolves the domain you care about". In split-routing mode, local-region domains resolving locally and international domains resolving through the tunnel is the intended design; forcing local-region domains through the tunnel only makes those sites slower.
A local resolver showing up in split-routing mode doesn't mean a leak. What you actually need to confirm is whether the DNS request for an international site goes out through the tunnel.
Step 3: per-app checks
The same node is captured differently by different apps. Assuming that "the browser works" means everything is routed is the most common misjudgement in troubleshooting.
- Browsers usually read the system proxy settings, so they're the easiest to route.
- Some desktop apps read the system proxy; others only work with TUN mode.
- Most command-line and developer tools don't read the system proxy — they need environment variables or TUN to be captured.
- Mobile devices are captured by a system-level VPN configuration, which has the widest coverage, but background battery-saving policies can cut the connection.
The test is simple: pick the same target, visit it once in the browser and once in the terminal, and compare the exit addresses. If both match, the capture scope reaches the command line; if only the browser changed, you're in system proxy mode, or the routing rules classify the terminal's target as direct.
Differences between platforms
On Windows, TUN mode requires installing a virtual network adapter, and the first connection asks for permission; on macOS you have to allow the network extension, and the client usually needs a restart before it takes effect; on Linux, TUN needs root privileges or the CAP_NET_ADMIN capability on the binary, otherwise only system proxy is available; iOS and Android use the system VPN framework, the first connection asks you to confirm the configuration, and the connection drops once the client is cleared from the background and has to be reopened. Subscription import differs too: desktop clients paste the subscription link and then refresh the node list manually once, while on mobile it's usually a single tap.
Three-check reference table
Here are the three steps compressed into one table — work through it row by row when troubleshooting:
| Check | How to test | Expected result | What it proves |
|---|---|---|---|
| Exit IP | IP lookup page, curl lookup endpoint |
The address after connecting is in the same region as the chosen node | Traffic really leaves through the node |
| DNS resolver | Leak test page, nslookup or dig |
International domains resolve inside the tunnel | Resolution isn't handed to the local ISP |
| Per-app capture | Visit once from the browser and once from the terminal | Both show the same exit address | The capture scope covers that app |
Common false positives
In each of these cases the client says Connected, but traffic isn't taking the international route as expected:
- ❌ The routing rules classify the test target as direct, so the exit address never changes.
- ❌ The system proxy is on, but the app under test doesn't read proxy settings — only the browser goes through the tunnel.
- ❌ Only IPv4 is captured; the local network has native IPv6, so IPv6-capable sites still go out locally.
- ❌ Traffic enters the tunnel, but DNS is still handled by the local resolver and results come back based on local position.
- ❌ QUIC-based protocols such as Hysteria2 and TUIC fail the handshake or reconnect constantly when the network blocks UDP, which looks like "it connects, then drops again after a while".
- ❌ The subscription link has expired or the node is offline; the client still lists the old route name, and tapping connect just retries over and over.
- ✅ The exit address changes to the node's location, international domains resolve inside the tunnel, and the browser and terminal agree — only when all three hold is traffic really routed.
Make the process repeatable
After every change of route, protocol or client, run the same sequence — far more reliable than going by feel:
- Record the exit address and resolver once before connecting, as a baseline.
- Connect to the node and note the region and protocol name you chose.
- Check the exit address again and compare the region with the chosen node.
- Check the resolver for an international domain to confirm resolution goes through the tunnel.
- Test once from the browser and once from the terminal, then compare the two.
- Repeat with another route or another protocol to confirm the problem isn't specific to one route.
Bottom line: the VPN is only really working when all three pass — the exit changed, resolution goes through the tunnel, and the app under test is covered. If only one of them holds, check the routing rules and capture mode first, and suspect the route itself last.
Once verification is done, confirm a few things on the service side
The exit address changes with the route you pick, and the cheaper it is to re-test on another route, the faster troubleshooting goes. VPNAJ currently covers 120+ countries and 180+ routes, with quantum encryption and no limit on simultaneous devices, so mobile, laptop and desktop can each run the three steps above; signing up needs only a username and password, no email address.
If the three checks still fail after two or three routes and two protocols, the problem is most likely in how traffic is captured locally rather than in the nodes. Fall back to TUN mode and test again, then consider reinstalling the client and re-importing the subscription link.
Tip: the value of verification is that it repeats. The same commands and the same table work today and work on another machine, so troubleshooting doesn't start from guesswork every time.