Android VPN export: what actually transfers to a new phone
An Android VPN export ships settings and sometimes a key, but never the device authorization. Check what actually moves before wiping the old phone.
Exporting a VPN profile from Android feels like a backup step, and the menu that offers it does nothing to correct that impression. What you walk away with is a parser input, a key the operating system may never hand back, and an authorization issued to that specific phone. Separate those three and the useful question appears: which piece is still missing on the new device?
The file is the easy part. The other two decide whether the migration works.
What an exported profile actually contains
Open the file in a text editor before you trust it. An OpenVPN profile is a small configuration language: remote, proto, data-ciphers, and often inline <ca>, <cert>, <key> or <tls-crypt> blocks that the client hands to its TLS stack. A WireGuard config is flatter, with [Interface] holding PrivateKey and Address, then one [Peer] per endpoint carrying PublicKey, AllowedIPs and Endpoint. IKEv2 arrives as a .mobileconfig with payload dictionaries instead of key blocks.
None of that text is a credential on its own. The credential is the private key, and each format either pastes it inline or points at an alias that only resolves inside the client that created it.
Where the key actually lives on Android
Android keeps app data under /data/data/<package>, readable by that app UID alone. There is no supported way to copy another app private directory from an unrooted phone, and adb backup stopped being a general answer once Android 12 deprecated it and clients started declaring allowBackup="false". So an export from an Android client means whatever that client implements, not a filesystem copy.
The identity layer sits underneath the app. If a client imported your key into the Android Keystore, the material is generated or wrapped there, and later exports can carry a reference to a Keystore alias instead of the bytes. Hardware-backed keys are built so that even the owning app cannot read them out, as the Keystore documentation describes, so a profile pointing at that alias imports cleanly on the same phone and fails everywhere else.
That is not a broken export. It is the property the platform was asked to provide.
What a profile cannot carry across
Line the objects up against what a destination will accept:
| Object | Transfers? | Why |
|---|---|---|
| Protocol and endpoint | Yes, if the destination client speaks it | Plain text in the profile |
| CA certificate and hostname check | Usually | Public material, but the hostname must still match the certificate |
| Client certificate | Yes, unless it is bound per device | Certificates are portable; the issuer decides how many devices may use one |
| Private key | Only if generated outside the Keystore | Hardware-backed keys cannot be exported, only replaced |
| Account, MFA, SSO session | No | Tokens expire and stay bound to the device that obtained them |
| Routes, DNS and app scope | Only as configuration text | Android applies them at connect time through VpnService.Builder |
| Split-tunnel app list | Rarely | Package names differ between devices, and the list is client state |
Two rows cause most of the confusion. A key generated on the device and marked non-exportable is genuinely gone with the app data, so the replacement is a new key plus a certificate issued to it. A session token copied to a new phone usually dies at the first refresh, which reads as a failed import.
Import is a parse, then a consent prompt
On the receiving side, import is a parse followed by a commit. The client reads the config, checks that every referenced block exists, then writes the tunnel definition into its own sandbox, which is why the file you picked from Downloads is not the thing that connects afterwards.
Then comes an authorization step no file can skip. Android requires the app to call VpnService.prepare() and receive your consent before it may establish a tunnel, so a freshly imported profile still shows the system dialog once. The tunnel is then built explicitly through addAddress, addRoute, addDnsServer, and addAllowedApplication or addDisallowedApplication for per-app routing. None of those are implied by an endpoint, so the same profile can produce a different effective route set in two clients.
Certificate-based setups add one more fork. When the server issues a certificate to a specific device, as MDM and SCEP enrollment do, reusing it on a second phone either works until the server enforces one session per identity or fails at the TLS handshake. Check the issuer policy before you plan to reuse it.
Verify the new device before you retire the old one
Keep the old phone connected until the new one has passed something better than a green icon. Confirm the exit address from the new device and the DNS resolver it actually used. If split tunneling matters, launch an app that should bypass the tunnel and one that should not, then see which one reaches your ISP.
One check settles the exit address. Open https://ifconfig.me in the phone browser, then run curl -s https://ifconfig.me from a laptop on the same Wi-Fi and compare both answers with the address your provider assigned.
Only then retire the old identity, and retire it through the issuer: revoke the certificate or remove the device from the account. Deleting a file from Downloads ends nothing, because two devices holding the same certificate look identical in the server log.
If the export turns out to be non-portable, the fix is a fresh enrollment rather than a public configuration bundle. Ask for a second device profile, or generate the key pair on the new phone and submit the CSR; slower, and it is the path the issuer supports.
Run the checklist before you delete anything: new device connects, exit address and DNS match, per-app scope is what you intended, old identity is revoked, and any config file you kept sits in encrypted storage.