A work app fails on a managed phone, someone checks the VPN toggle, sees it on, and declares the path healthy. That is where most of these diagnoses stop, and it is too early: an active VPN transport does not say that this app's requests used it, and the proxy that actually applies may be per-app or chosen by a PAC file rather than shown in Settings. Start from the specific app and profile you are debugging, then read the platform's own view of the path.

Start from the app and its profile

A work-badged app usually runs in a separate profile with its own network policy. A personal browser on the same phone is not evidence for it, and neither is a result from a colleague's device with different management. Note which profile the app belongs to before you read anything.

In Settings, list the configured VPN entries and note who owns each. On Samsung builds the menu labels move between releases, so describe the entry rather than the path to it. A greyed-out or managed entry belongs to whoever administers the device; switching it off as an experiment changes the thing you are trying to measure and may be against policy.

Read the state the platform reports

Inside an existing activity in your support tooling, on API 23 or later, the network state can be read without sending a byte. The call needs the normal ACCESS_NETWORK_STATE manifest permission for the capability read.

val cm = getSystemService(android.net.ConnectivityManager::class.java) ?: return
val network = cm.activeNetwork
val caps = network?.let { cm.getNetworkCapabilities(it) }
val hasVpn = caps?.hasTransport(android.net.NetworkCapabilities.TRANSPORT_VPN)
val proxy = cm.defaultProxy

Each value answers a narrow question. The active network is the default network for the calling process at that moment. The capability check tells you whether that default network is VPN-backed. The proxy call reports the effective default HTTP proxy, and a returned object may describe either a static proxy or a PAC script.

If you need the per-network view instead of the default, read the link properties of the same network and compare with cm.getLinkProperties(network)?.httpProxy. A proxy installed by device management shows up in the default-proxy call and not in the link properties, which is a quick way to tell a policy-supplied proxy from one the network handed out.

Keep the output in your support channel rather than a public report. Proxy hostnames, PAC URLs and internal suffixes disclose how your organisation routes traffic, and none of them are needed to describe the failure.

Interpret every field narrowly

A null network or a null capability object means the caller's network state was unavailable or changed during the read. It does not mean there is no VPN. Treat it as unknown and read again after the app has foregrounded, rather than as a negative result.

A VPN transport is the weakest of the positives. Any app holding a VpnService produces one, including a local filtering app that never sends your traffic anywhere. So a true value says a VPN-backed default network exists, not that your organisation's exit was used and certainly not that inspection happened.

A null default proxy means that this API reports no default HTTP proxy for the effective configuration. It rules out very little: an app can carry its own SOCKS setting, implement its own HTTP client, or be steered by a proxy at the gateway that the device never learns about.

PAC is the case that defeats a single-value answer. A script can route one destination through a proxy and send another direct, so two requests from the same app within a second may take different paths. And an app that binds its sockets to a chosen network, or calls bindProcessToNetwork, is not obliged to follow the default at all.

What this snapshot cannot tell you

It is not a history. Nothing here records which path the failing request took, and a successful read after the failure is not evidence about the failure. It is also not an inventory: you get the calling process's default network, not a list of every app's private connections.

It says nothing about what happens above the socket either. A TLS handshake that fails on a managed device may be a trust-store problem, a pinning mismatch or a name the proxy refuses, and none of those appear in a connectivity read.

That is why the two halves matter together: the snapshot narrows where to look, and the app's own diagnostics say what actually failed.

Report it in a form an administrator can use

Give the affected app, the profile, the timestamp, and the exact stage that failed: name resolution, TCP connect, TLS handshake or an HTTP status. Add the snapshot values as they were read, with nulls written as nulls rather than as none. Note whether other apps in the same profile fail the same way, which separates an app problem from a profile-wide path problem.

Then stop and let the owner of the path respond. Do not treat a corporate certificate, a proxy address or a VPN entry as permission to remove management or to bypass the approved route; that converts a support case into a policy incident.

The default-proxy contract is short and worth reading once, because it defines exactly which proxy the call reports, and every over-reading of this snapshot starts with assuming it reports more.

مۇناسىۋەتلىك ماقالىلەر