To check whether a VPN is working, you cannot rely only on the client showing “Connected.” This status usually means the handshake completed or the tunnel was created; it does not mean that traffic from your browser, command-line tools, and other apps is using the intended route. A reliable check should compare the public IP, DNS lookup path, and actual app behavior.
A complete check has three layers: first confirm the protocol connection between the client and node, then confirm that the operating system sends the target traffic into the tunnel, and finally verify that the destination sees the expected public IP. Checking only one layer can make you mistake “protocol connected but routing not engaged” for a healthy connection, or mistake a browser’s own proxy or DNS settings for a system-wide VPN connection.
First, distinguish “connection succeeded” from “traffic is using the route”
When a client connects, it first establishes a transport channel with the remote server. Shadowsocks, VMess, Trojan, VLESS, Hysteria2, and TUIC can all handle this stage, but after the handshake succeeds, whether traffic enters the channel depends on the client mode, system permissions, and routing rules.
For example, in system proxy mode, usually only apps that follow the system proxy settings use the proxy. A browser may switch its public IP normally, while some games, command-line programs, or desktop apps with their own network stack continue to connect directly. In virtual adapter or tunnel mode, the client can capture more system traffic, but routing priority, exclusion rules, other network tools, and system permissions can still affect the result.
Therefore, “Connected” may correspond to several different outcomes:
- The protocol handshake completed, and the browser and other apps are using the route as configured.
- The protocol handshake completed, but only apps using the system proxy are using the route.
- The protocol handshake completed, but split-tunneling rules classified the current destination as direct.
- The tunnel was created, but system routes were not written correctly or were overwritten by another configuration.
- Most web traffic uses the route, while DNS queries or some address-family traffic still leaves through the local network.
- A browser extension or in-app proxy changes the result, making its public IP differ from the system’s.
During troubleshooting, do not keep switching nodes and watching only the status indicator. A more effective approach is to keep one target route fixed, record network results before and after connecting, and narrow the issue down layer by layer. This helps identify whether the problem is in the protocol, routing, DNS, split tunneling, or a specific app.
Use the public IP to confirm the actual traffic path
The public IP is the source address seen by the destination website and the most direct way to determine whether web traffic is using a remote node. Before testing, disconnect the client, visit a trusted IP lookup page, and record the local public IP. Then connect to the selected route, run the lookup again, and compare the results. If the address and geographic location change with the node, the lookup request is leaving through the remote exit.
Keep the network environment as consistent as possible during testing. Do not switch between Wi-Fi, Ethernet, or another access method before and after connecting, or the local public IP may change on its own and make the comparison meaningless. Browser pages may also cache earlier results; hard-refresh the page or repeat the lookup in a new private window if needed.
What to check when the public IP does not change
An unchanged public IP does not necessarily mean the node is unavailable. Common causes include the browser not using the system proxy, the client only starting a local proxy port, the virtual adapter lacking required permissions, or split-tunneling rules classifying the IP lookup site as direct. First check whether the client is using system proxy, rule mode, global mode, or tunnel mode.
If the public IP changes in global mode but not in rule mode, the issue is usually rule matching rather than the protocol connection. Review the connection log to see whether the lookup site’s domain matched a proxy rule or a direct rule. “Connection successful” in the log only proves that the client can reach the remote server; the diagnostically useful detail is which outbound route handled the request.
When different apps show different public IPs
If the browser, terminal, and desktop app show different public IPs, they are usually not sharing the same proxy entry point. The browser may have an independent proxy extension, the terminal program may ignore the system proxy, and some apps may prioritize their own network channel. Disable in-app proxies individually, or explicitly point each app to the local proxy entry provided by the client, then test again.
| Observed result | Possible cause | Next step |
|---|---|---|
| Public IP changes after connecting | The lookup traffic is using the selected route | Continue by checking DNS and the actual apps |
| Public IP remains unchanged | Proxy not engaged, direct rule matched, or route not written | Switch test modes and review the connection log |
| Browser changes, other apps do not | Only the browser is using the proxy | Check the system proxy, tunnel mode, and app settings |
| Different lookup pages show conflicting results | Caching, address-family differences, or different page-detection data | Refresh the results and verify through multiple network entry points |
Check whether DNS queries bypass the tunnel
When you visit a domain, the system first resolves it to a reachable address. If web traffic uses the VPN while DNS queries still go to a resolver provided by the local network, the page may load normally even though the DNS path and web exit do not match. This is commonly called a DNS leak; more precisely, the resolution request did not enter the controlled channel as expected.
During testing, check the DNS resolver’s location and provider both while disconnected and while connected. If queries continue to use the original local resolver after connecting, inspect the client’s DNS interception, virtual adapter configuration, and system cache. If the result shows the remote resolver configured by the client or an in-tunnel resolver, the DNS path is closer to the expected setup.
DNS results must still be interpreted alongside the configuration. A browser may enable encrypted DNS and bypass the operating system’s resolver settings, while a client may choose different resolvers by domain category. A resolver in a different region from the public IP is not automatically a leak; the key question is whether the path matches the client’s design and your settings.
How encrypted DNS in the browser can change the result
Modern browsers can send encrypted DNS requests on their own. As a result, browser lookups may differ from system commands, other apps, and client logs. If the browser’s encrypted DNS requests still travel through the tunnel, this does not necessarily indicate bypassing; but if the routing rules allow those requests to go direct, they create a path separate from system DNS.
For troubleshooting, temporarily make the browser follow the system resolver settings and run the test again. If the results become consistent, the difference came from the browser’s own configuration. If they remain different, continue by checking the client’s DNS rules, the virtual adapter’s coverage, and the order of system network services.
System caching and stale DNS results
Both the operating system and browser may cache DNS records. After switching routes, existing connections may also be reused, making the page appear to follow the old path even though the new public IP is already active. Before testing, close the relevant pages, clear the system DNS cache, and reopen the browser. There is no need to clear caches routinely; do so only when diagnosing a path change.
Windows:
ipconfig /all
macOS:
scutil --dns
Linux:
resolvectl status
These commands show the resolver configuration currently recognized by the system; they do not mean every app follows that configuration. Interpret the command output together with client logs, browser settings, and actual DNS lookup results.
Test apps individually: a working browser does not mean everything works
After checking the public IP and DNS, test the apps you actually plan to use one by one. This may include a browser, command-line download tool, desktop client, video app, and real-time communication program that requires UDP. The goal is not for every app to show identical screens, but to confirm that each app’s connection reaches the intended outbound route.
The simplest method is to watch for a new connection in the client log. Launch the target app, perform one clear network action, and check whether the relevant domain or address was assigned to the proxy, direct route, or blocked route. If the app produces no request in the log at all, it may be outside the client’s interception scope or using a network protocol the client does not currently handle.
System proxy versus tunnel mode
System proxy mode works well for websites and desktop software that follow proxy settings. It is relatively straightforward to configure, but cannot guarantee coverage for every process. Tunnel mode receives system traffic through a virtual network interface and is generally better when traffic needs to be captured consistently. When enabling tunnel mode, check system permissions, the default route, DNS interception, and local-network access rules.
If system proxy tests work but tunnel mode does not, check whether the virtual adapter was created successfully, whether another VPN or security tool rewrote the routes, and whether the client excluded the current network interface. Conversely, if tunnel mode works but system proxy mode does not, verify that the operating system proxy switch was written successfully and that the app supports the selected proxy type.
How split-tunneling rules affect verification
Rule mode selects an outbound route based on domains, address ranges, process names, or rule sets. When a rule is wrong, the client may still show a healthy connection while the target request goes directly. This is especially common after redirects, when an app connects to a content-delivery domain, or when rules cover only the primary domain rather than all domains in the request chain.
To diagnose rule problems, temporarily switch to global proxy mode for comparison. If the target app works in global mode but fails in rule mode, check rule order, domain matching, and the final fallback route. Restore the required split-tunneling settings after troubleshooting; there is no need to rely on global mode permanently.
UDP and QUIC-based connections
Some websites, real-time communication tools, and games use UDP. If the client only captures TCP, or the current network restricts UDP, the app may fall back to another transport or fail outright. Hysteria2 and TUIC are based on QUIC and UDP, so node handshakes, underlying network reachability, and the client’s ability to forward UDP all affect the result.
The behavior of Trojan, VMess, VLESS, and Shadowsocks also depends on the client implementation, transport configuration, and routing method. You cannot determine system-wide coverage from the protocol name alone. The protocol defines how the client and server exchange data; system proxy settings, virtual adapters, and split-tunneling rules determine which app traffic enters that channel.
| Test subject | What to observe | Clues to an issue |
|---|---|---|
| Browser | Public IP, DNS, and independent browser proxy | Extension or encrypted DNS bypassing system settings |
| Command-line tool | Whether it reads proxy environment variables or enters the tunnel | Terminal public IP differs from the browser’s |
| Desktop app | Process rules and in-app network settings | No corresponding connection appears in the log |
| Real-time communication app | UDP interception and connection fallback | Web pages work but real-time connections fail |
How protocols, subscriptions, and node types affect the result
A subscription link usually contains node names, server parameters, protocol types, and transport settings. After importing it, the client converts that information into a local configuration. A successful import only means the client can read the subscription; it does not mean the selected node is connected or that the routing rules automatically fit the current platform.
If the service stops working immediately after a subscription update, first confirm that the current node still exists, that the protocol fields are supported by the client, and that the update did not overwrite local split-tunneling settings. Some clients manage nodes, proxy groups, DNS, and routing rules separately. Selecting a new node while still using an old proxy group is another common reason for inconsistent results.
What to check for different protocols
- Shadowsocks: Check whether the client only opened a local proxy or also enabled the system proxy or virtual adapter. Starting a local listener alone does not automatically capture every app.
- VMess and VLESS: In addition to the node connection, check the transport settings, outbound policy, and routing rules. VLESS security depends on the chosen transport and security settings, so it cannot be assessed separately from the complete configuration.
- Trojan: Confirm that the transport security parameters match the target server. A failed handshake is a protocol-layer issue; if the handshake succeeds but the public IP does not change, return to the routing layer.
- Hysteria2 and TUIC: Focus on whether UDP is reachable on the current network and whether the client handles UDP traffic correctly. When the network environment changes, they may behave differently from TCP-based options.
Direct, relay, and IEPL routes
A direct route usually connects the user’s network straight to the remote node, so its performance depends more heavily on changes in public routing. A relay route connects to an intermediate entry point first, then sends traffic through the relay to the exit node. This can reduce exposure to some unpredictable public-network paths, but the actual result still depends on the entry point, carrier network, and exit configuration.
IEPL generally refers to a type of link carried over a cross-border enterprise private line. An IEPL label does not mean that every segment—from the user’s device to the entry point, from the entry point to the exit, and from the exit to the destination website—is outside the public internet. Verify using the actual public IP, DNS path, connection logs, and target-app results rather than relying only on the node name.
After switching between a direct, relay, or private-line node, repeat the same checks. Changing the route type may change the public IP and transport path, but it does not automatically fix an app that is not being captured, incorrect DNS settings, or conflicting split-tunneling rules.
Common platform differences and troubleshooting order
Windows clients often provide both system proxy and virtual adapter modes. Whether the system proxy was written successfully, whether the virtual adapter driver works correctly, and whether another tool changed interface priority can all affect the result. Start by checking the system proxy status, then review routing and DNS settings, and finally compare different apps.
macOS applies explicit permission controls to network extensions and system proxies. When a tunnel is enabled for the first time, the client may save the node configuration but fail to capture traffic if the network extension was not approved. Also note that the browser, terminal, and system network services may read different proxy environments.
On iOS, clients usually capture traffic through the system VPN configuration, but on-demand connections, app rules, and system privacy features can change the test result. After switching nodes, send a new request instead of observing a connection that is still being reused. If one app fails while the browser works, fully close that app and reopen it first.
Android behavior is affected by system VPN permissions, battery-saving policies, per-app proxy settings, and the always-on option. If the system pauses the client in the background, the interface may retain its previous status while new requests can no longer use the tunnel. Check that the VPN status in the system status bar, the client’s running state, and the per-app list agree.
Linux depends more heavily on the specific desktop environment, routing tools, and permission settings. Setting a desktop proxy alone does not automatically affect every shell command or background service; virtual adapter mode requires the interface to be created correctly and routes to be added. With containers or separate network namespaces, container traffic may not inherit the host’s path.
A complete troubleshooting flow for “Connected but inaccessible”
When the client says “Connected” but pages will not open, following a fixed order is more effective than randomly changing protocols. Record the result at each step so you can distinguish a node failure, a network restriction, and a local configuration problem.
- Record the pre-connection baseline. Disconnect the client, confirm that the local network works, and record the public IP and DNS resolution path.
- Connect to one fixed node. Do not switch through several nodes in a row. Wait for a clear handshake or connection acknowledgment, and check for authentication, timeout, or transport errors.
- Check the public IP again. If it has not changed, check the proxy mode, virtual adapter permissions, routing rules, and whether the lookup site matched a direct route.
- Check DNS again. Confirm that the system and browser use the expected resolution path, and rule out interference from caching and the browser’s independent encrypted DNS.
- Compare global and rule modes. If global mode works but rule mode does not, focus on rule matching and the fallback outbound route.
- Test apps one by one. Check whether the client log shows the corresponding request and whether it ultimately uses the proxy, direct route, or blocked route.
- Check protocol and network compatibility. If a UDP-based protocol cannot complete its handshake, compare it with another working transport on the same network to determine whether the underlying network is restricting it.
- Rule out configuration conflicts. Temporarily disable other proxies, VPNs, browser extensions, or network tools that may rewrite routes, then establish the connection again.
- Re-import or update the subscription. Confirm that the client supports the protocols and fields in the subscription, and check whether the update changed the proxy group, DNS, or local rules.
If a step restores normal behavior, save the current configuration before making further changes. Changing several options at once makes the cause difficult to identify. The goal is not simply to turn the status light green, but to establish a repeatable path: the protocol handshakes, routing captures traffic, DNS follows the intended settings, and the target app receives the expected public IP.
The most reliable verification combines connection logs, public IP results, the DNS path, and actual app behavior. Any conflict means that some traffic is still not following the expected path.
How to tell whether the issue is resolved
After fixing the issue, start verification from the baseline again instead of retrying only the page that failed. Once connected to the target route, the public IP should differ from the disconnected state and match the selected exit; DNS queries should follow the client’s settings; and the browser, terminal, and main apps should use the appropriate outbound routes according to the split-tunneling rules.
With rule mode enabled, local sites staying direct while a selected destination uses the route is not a contradiction—it is the expected result of split tunneling. To judge whether the VPN is working, compare the intended rules with the actual paths rather than requiring every request to show the same public IP. For explicitly excluded local-network resources, also confirm that they remain accessible through the local network.
Finally, disconnect and reconnect once to check whether the result is reproducible. If the first test succeeds but the configuration is lost after reconnecting, continue checking system permissions, startup items, subscription proxy groups, and network interface settings. A repeatable result is more useful for diagnosis than a page working once.