The most direct way to confirm a VPN is working isn't the "Connected" label in the client — it's checking three things separately: exit IP, DNS ownership, and per-app routing. Only when all three pass is your traffic really going through the route; if any one fails, it's the "looks connected, but isn't" case.
This article breaks the three layers into repeatable steps: for each layer, the metric to watch, how to check it, and what to fix when it fails. A quick-reference table of typical cases and a self-check list are at the end.
Why "Connected" Doesn't Mean Traffic Is Going Through the Route
The connection status in the client means the local proxy process has started and a session with the entry node is established. It doesn't check where each app's traffic goes afterwards — that's decided by the connection mode, routing rules, and the per-app list.
There are three common kinds of "leaks" that all look connected:
- In rule (split-tunnel) mode, the target domain is judged as direct, so that traffic never enters the route;
- In per-app mode, the current app isn't ticked, so its traffic still leaves through the local network;
- The browser or another app has its own proxy settings, layering on top of the system and sending traffic elsewhere.
Another way to think about it: "working" means the traffic that should go through the route really exits from the route, and both resolution and scope line up. It isn't a status light in the client — it's the result of three checks together.
Layer 1: Check whether the exit IP actually changed
The method is simple: disconnect the client and note your direct exit IP and its location; then connect to the target route and check again. Compare two things — whether the address changed, and whether the location matches the country/region listed for that route.
When checking, prefer an IP lookup site that shows location — a bare string of numbers won't tell you the region. Command-line users can compare directly:
# Record once while the client is disconnected
curl -s https://ifconfig.me; echo
# Check again after connecting to a route, and compare
curl -s https://ifconfig.me; echo
# Check the IPv6 exit separately (some routes only handle IPv4)
curl -s -6 https://ifconfig.me; echo
Check IPv4 and IPv6 separately. Some routes only handle IPv4; if your machine also has an IPv6 exit, IPv6 requests may still leave through the local network — which shows up as "some sites go through the route, some don't".
If the results show two addresses, verify the location of both. If only one changed, the other protocol stack isn't going through the route — confirm how the client handles IPv6, or temporarily disable IPv6 and test again.
A changed exit IP only proves that some traffic went through the route — not that all the traffic that should go through did. Once this layer passes, move on to DNS.
Layer 2: Check whether DNS ownership follows
DNS requests and web traffic are two separate channels. Even when page content travels through the route, domain resolution may still go to your local ISP's DNS — this is usually called a DNS leak.
A leak has two consequences: first, resolution results come back based on your real location, so you may get a local CDN node and see page language and pricing for the wrong region; second, the resolution request exposes your real network location, which defeats the purpose of using a route.
The check has two steps: first see which DNS server your machine is using, then have a resolver report the source address it sees and look up its location.
# Show the DNS servers your machine is currently using
ipconfig /all # Windows
scutil --dns # macOS
resolvectl status # Linux
# Have the resolver report the source address it sees, for a location lookup
dig +short TXT o-o.myaddr.l.google.com @8.8.8.8
If the resolving server still belongs to your local ISP, try these in order, depending on what the client supports: enable the client's DNS override / remote DNS option; switch to encrypted DNS (DoH / DoT) and confirm that traffic also goes through the route; check whether the browser has its own "secure DNS" enabled — built-in browser DoH bypasses system DNS settings and sends resolution out another way.
Layer 3: Per-app verification of traffic scope
The first two layers verify whether the route works and whether resolution is clean; the third verifies scope: which apps and which domains are counted as going through the route.
Clients usually offer three modes. Global mode sends all traffic through the route; rule (split-tunnel) mode decides by domain, IP range, and GeoIP; direct mode doesn't use the route at all. Mobile clients add a per-app list, and only the apps you tick are taken over.
The test is a side-by-side comparison: on the same device, open an exit lookup page in two different apps and see whether the exit IP matches. If one shows the route exit and the other shows your local exit, one of the apps isn't being taken over. On desktop you can also check the client's connection log or rule-hit records to see which rule the target domain matched and whether it went proxy or direct.
Also, rule-based routing usually relies on domain, IP range, and GeoIP databases, and those databases update on a cycle, so newly appearing domains are occasionally misjudged. This is one common reason "it worked yesterday but went direct today" — check the rule-hit records first before blaming the route.
Per-app verification is valuable because it rules out "the route is fine, one app just isn't being taken over". This case is easily mistaken for a route failure: change settings first, and only then consider switching routes.
Typical cases where it "looks connected but isn't"
The table below puts common symptoms, causes, and fixes side by side — work through it by symptom and you can usually pinpoint the issue in minutes. Fixes are ordered "change settings first, switch routes later".
| Symptom | Likely cause | Fix |
|---|---|---|
| Exit IP is exactly the same as before connecting | The client is in per-app mode and the current app isn't ticked; or a rule judges the target domain as direct | Tick the app in the per-app list, or switch to global mode and test again |
| Exit IP changed, but the page is still in your local language and local pricing | DNS requests are still resolved by the local ISP, and the CDN routes to the nearest node based on resolution location | Enable the client's DNS override / remote DNS, or switch to encrypted DNS that also goes through the route |
| It works in the browser but not in other apps | The browser has its own proxy extension or separate proxy settings taking over its traffic | Turn off the browser proxy extension, let the client handle everything, and test again |
| After updating the subscription, the route list is still the old one | The client hasn't refreshed the subscription and is still using old node information | Update the subscription manually in the client, or re-import the subscription link and restart the client |
| It shows connected, but no website will open | The node is unavailable, or a rule sent traffic to an unreachable exit | Switch to another route and test again; if it still fails, switch to global mode to see whether rules are involved |
- ❌ Judging by the "Connected" label on the client's home screen alone — it doesn't mean app-level traffic actually goes through the route
- ❌ Testing the exit with only one website — nearby routing or caching can mislead you
- ❌ Leaving another proxy extension enabled in the browser — you may be measuring that extension's exit
- ❌ Not restarting the client after updating the subscription — the old connection is still active and the new node info hasn't been applied
A repeatable three-layer self-check routine
Putting the earlier methods together gives the five steps below. Run them after switching networks (home, office, public Wi-Fi), updating a subscription, or changing routes — no need to test on every connection.
- Disconnect the client and record your direct exit IP and its location, checking IPv4 and IPv6 separately.
- Connect to the target route, look up the exit IP again, and confirm the address changed and the location matches the route label.
- Open a DNS leak test page and confirm the resolving server belongs to the route side, not your local ISP.
- Open the exit lookup page in two different apps and confirm the exit matches; then check the rule hits in the client log.
- Once all three layers pass, test speed and stability. If any layer fails, change settings first — don't rush to switch routes.
- ✅ Exit IP matches the route's country/region, and IPv4 and IPv6 behave the same way
- ✅ The resolving server belongs to the route side, and no local ISP appears in the list
- ✅ The target app is taken over by the client and shares the same exit as other apps
- ✅ In the rule-hit records, the target domain goes proxy rather than direct
A subscription link is as sensitive as account credentials. Screenshots or forwarding it to a public group can leak it; if it leaks, reset the subscription link in the user panel — the old link stops working immediately — then re-import it in the client.
Keep the three layers in order: exit IP answers "did it go through", DNS answers "is it clean", and per-app answers "is the scope right". Only when all three pass is it really working.
FAQ
The client says connected — do I still need to verify every time?
No. Just check once after switching networks (home, office, public Wi-Fi), updating a subscription, or changing routes. For everyday use, the exit IP layer alone covers most cases.
The exit IP changed, but websites still show the local version — what's wrong?
Most likely DNS is still resolving locally and the CDN returns a nearby node based on resolution location. Check the resolving server's location using the layer-2 method, then enable the client's DNS override or remote DNS option.
In per-app mode, do I need to tick background apps too?
As needed. For heavy background tasks like system updates and app stores, leaving them on direct is usually better; tick only the apps that really need the route. Fewer rules make troubleshooting easier.
All three layers pass, but browsing is still slow — is it the route?
Check the scope first: if only one website is slow, it's usually that site's CDN routing or local network fluctuation; if multiple routes and multiple websites are slow, then consider switching routes. Also, confirm the three layers pass before running a speed test, otherwise you may be measuring your direct local connection.