ByteScope

APK Installer

Drag an Android package onto a phone over USB — split picking, version and signature checks, and every INSTALL_FAILED code explained.

APK files are opened in this browser and streamed straight to the phone over USB. Nothing is uploaded.

Checking browser support…

INSTALL_FAILED_* reference

Every failure code this page recognizes, what it means, and what to do about it. The codes are Android's own constants — the same ones desktop `adb install` prints.

Something already installed is in the way

INSTALL_FAILED_ALREADY_EXISTS
This package is already installed and the install was not told to replace it.
  • Remove the installed copy first, then install again. You lose that app's data.
INSTALL_FAILED_UPDATE_INCOMPATIBLE
An app with this package name is already installed but signed with a different key, so Android will not treat this as an update.
  • Compare the signing certificate with the installed app's. Android will not replace an app with one signed by a different key.
  • Remove the installed copy first, then install again. You lose that app's data.
INSTALL_FAILED_VERSION_DOWNGRADE
The APK's version code is lower than the installed one's, and downgrades are refused by default.
  • Turn on “allow downgrade” (`-d`) and retry — or uninstall the newer version first. Data written by the newer version may not load in the older one.
  • Remove the installed copy first, then install again. You lose that app's data.
INSTALL_FAILED_DUPLICATE_PACKAGE
Another package on the device already uses this package name.
  • Remove the installed copy first, then install again. You lose that app's data.
INSTALL_FAILED_SHARED_USER_INCOMPATIBLE
The APK declares a `sharedUserId` that clashes with an app already installed under that shared user.
  • Remove the installed copy first, then install again. You lose that app's data.
  • Compare the signing certificate with the installed app's. Android will not replace an app with one signed by a different key.
INSTALL_FAILED_UID_CHANGED
The installed app owns a Linux UID this install would have to change, which would orphan its existing data.
  • Remove the installed copy first, then install again. You lose that app's data.
INSTALL_FAILED_REPLACE_COULDNT_DELETE
Android could not remove the previous version to put this one in its place.
  • Reboot the phone and try again.
  • Remove the installed copy first, then install again. You lose that app's data.
INSTALL_FAILED_DUPLICATE_PERMISSION
The APK defines a permission name that another installed app already defines.
  • Another installed app already claims the same content authority or permission name. Find and remove it, then retry.
INSTALL_FAILED_CONFLICTING_PROVIDER
The APK declares a content provider authority that another installed app already owns.
  • Another installed app already claims the same content authority or permission name. Find and remove it, then retry.
INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE
The installed app uses runtime permissions and this APK targets an Android old enough to use the install-time model — that direction is not allowed.
  • Remove the installed copy first, then install again. You lose that app's data.

The APK and this device do not fit each other

INSTALL_FAILED_OLDER_SDK
The APK requires a newer Android than this phone runs (`minSdkVersion` is above the device's API level).
  • The APK's declared SDK range does not fit this Android version. Check `minSdkVersion` / `targetSdkVersion` against the phone's release.
INSTALL_FAILED_NEWER_SDK
The APK was built for an older Android than this phone runs and its declared maximum SDK excludes this device.
  • The APK's declared SDK range does not fit this Android version. Check `minSdkVersion` / `targetSdkVersion` against the phone's release.
INSTALL_FAILED_NO_MATCHING_ABIS
The APK contains native libraries, but none for a CPU architecture this phone supports.
  • This APK carries no native code for the phone's CPU. Get a build for the device's ABI, or install the whole split set instead of one APK.
  • Install the whole split set from the container, not a single APK out of it — a split cannot be installed on its own.
INSTALL_FAILED_CPU_ABI_INCOMPATIBLE
The APK's native code does not match the phone's CPU architecture.
  • This APK carries no native code for the phone's CPU. Get a build for the device's ABI, or install the whole split set instead of one APK.
INSTALL_FAILED_MISSING_FEATURE
The APK requires a hardware or software feature this device does not report having.
  • The APK's declared SDK range does not fit this Android version. Check `minSdkVersion` / `targetSdkVersion` against the phone's release.
INSTALL_FAILED_MISSING_SPLIT
This is one piece of a split app and the pieces it depends on are not installed — a config or feature split cannot stand on its own.
  • Install the whole split set from the container, not a single APK out of it — a split cannot be installed on its own.
INSTALL_FAILED_DEPRECATED_SDK_VERSION
Android 14 and later refuse to install apps targeting a very old SDK level, whatever their signature.
  • The APK's declared SDK range does not fit this Android version. Check `minSdkVersion` / `targetSdkVersion` against the phone's release.

Storage

INSTALL_FAILED_INSUFFICIENT_STORAGE
There is not enough free space on the device for this app.
  • Free space on the phone and retry — an install needs room for the APK plus its compiled code.
INSTALL_FAILED_MEDIA_UNAVAILABLE
The storage volume the install targeted is not mounted or went away mid-install.
  • Try again — this failure is usually transient.
  • Reboot the phone and try again.
INSTALL_FAILED_CONTAINER_ERROR
Android could not prepare the container the app's files are copied into — usually a storage problem underneath.
  • Free space on the phone and retry — an install needs room for the APK plus its compiled code.
  • Try again — this failure is usually transient.

A verifier, a policy or a build flag refused it

INSTALL_FAILED_TEST_ONLY
The APK is marked `android:testOnly`, which normal installs refuse.
  • Turn on “allow test builds” (`-t`) and retry. The APK was built as a debug/test artifact.
INSTALL_FAILED_VERIFICATION_FAILURE
The package verifier — Play Protect on most phones — examined the APK and rejected it.
  • Play Protect scanned the APK and refused it. Turn off “Scan apps with Play Protect” or “Verify apps over USB” in Developer options, then retry.
  • Try again — this failure is usually transient.
INSTALL_FAILED_VERIFICATION_TIMEOUT
The package verifier did not answer in time, so the install was cancelled.
  • Try again — this failure is usually transient.
  • Play Protect scanned the APK and refused it. Turn off “Scan apps with Play Protect” or “Verify apps over USB” in Developer options, then retry.
INSTALL_FAILED_USER_RESTRICTED
A device policy or a user restriction forbids installing apps this way.
  • Unlock the screen and answer any prompt on the phone — some installs need an on-device confirmation and time out silently without one.
  • A work profile, device owner or parental-control policy is blocking installs. Check Settings → Users, or ask whoever manages the device.
INSTALL_FAILED_ABORTED
The install session was cancelled before it committed — often an unanswered on-device prompt, a locked screen, or another install that took the session away.
  • Unlock the screen and answer any prompt on the phone — some installs need an on-device confirmation and time out silently without one.
  • Try again — this failure is usually transient.

The file could not be read as an APK

INSTALL_FAILED_INVALID_APK
Android could not accept the APK as a valid package — a corrupt archive, a broken split set, or a split written into the session twice.
  • Install the whole split set from the container, not a single APK out of it — a split cannot be installed on its own.
  • The file is not a valid APK, or it arrived damaged. Download it again from the original source.
INSTALL_FAILED_BAD_SIGNATURE
The APK's signature did not verify: the file has been modified since it was signed, or the signature block is malformed.
  • Compare the signing certificate with the installed app's. Android will not replace an app with one signed by a different key.
  • The file is not a valid APK, or it arrived damaged. Download it again from the original source.
INSTALL_PARSE_FAILED_NOT_APK
The file is not an APK at all — the installer could not read it as one.
  • The file is not a valid APK, or it arrived damaged. Download it again from the original source.
INSTALL_PARSE_FAILED_NO_CERTIFICATES
The APK carries no valid signature. Unsigned APKs, and APKs whose signature files were stripped when they were repacked, land here.
  • The file is not a valid APK, or it arrived damaged. Download it again from the original source.
  • Compare the signing certificate with the installed app's. Android will not replace an app with one signed by a different key.
INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES
The APKs in this set are not all signed by the same key — every split of one app must share the base's signature.
  • Compare the signing certificate with the installed app's. Android will not replace an app with one signed by a different key.
  • The file is not a valid APK, or it arrived damaged. Download it again from the original source.
INSTALL_PARSE_FAILED_MANIFEST_MALFORMED
The APK's `AndroidManifest.xml` could not be parsed.
  • The file is not a valid APK, or it arrived damaged. Download it again from the original source.

The install session or the framework failed

INSTALL_FAILED_INTERNAL_ERROR
The package installer hit an internal error and did not say more.
  • Try again — this failure is usually transient.
  • Reboot the phone and try again.
INSTALL_FAILED_DEXOPT
Compiling the app's code after copying it failed — usually not enough free space, sometimes a corrupt DEX.
  • Free space on the phone and retry — an install needs room for the APK plus its compiled code.
  • Reboot the phone and try again.
  • Try again — this failure is usually transient.
About this tool, FAQ and related tools

About this tool

Plug an Android phone into a Chromium browser over USB, drop one or more packages on this page, and they install one after another. .apk goes straight to the device installer; .apks, .xapk and .apkm are containers of split APKs, so they are unzipped in the browser, the splits this particular phone needs are selected, and all of them are written into a single install session. Nothing is uploaded anywhere — the bytes go from the file on your disk into cmd package install-write over the USB cable, and the page is a static file with no server behind it.

What a split APK is, and why the app you downloaded is in pieces

Since 2018 the Play Store has not shipped one APK per app. It ships an *app bundle*, and the store builds a set of APKs out of it for each device: a base APK with the code, one config split per CPU architecture, one per screen density, one per language, and one per optional feature module. Your phone downloads four or five of them; the other twenty are for other phones. That is why an app that is 90 MB on the store is a 400 MB .apks when someone exports the whole set, and why installing only the base APK out of that set gives you an app that starts and immediately crashes with an UnsatisfiedLinkError — the native code lives in the ABI split you left behind. Android accepts **at most one config split per dimension** in a session; two ABI splits, or two densities, is INSTALL_FAILED_INVALID_APK after the entire upload has been paid for.

.apks, .xapk, .apkm — the same idea, three packagers

.apks is bundletool's own output — the file bundletool build-apks produces, carrying a toc.pb that names every split and the device conditions it applies to. .xapk comes from APKPure, and carries a manifest.json with the package name, version and the split list. .apkm is APKMirror's, with an info.json; note that the *older* encrypted .apkm files cannot be opened by anything but APKMirror's own installer, and this page says so rather than failing obscurely. SAI (Split APKs Installer) writes a meta.sai_v2.json. All four are ZIP files with a metadata sidecar, and this page reads whichever one is present and falls back to filename patterns when a container was repacked by hand.

Why a different signing key always fails, and what to do instead

Android identifies an app by its package name *and* the certificate it was signed with. Replacing an installed app with one signed by a different key would let anyone who could guess a package name publish an update to somebody else's app, so the platform refuses: INSTALL_FAILED_UPDATE_INCOMPATIBLE. There is no flag for it. The only ways through are to uninstall the installed copy first — which deletes its data, so export anything you care about beforehand — or to have an APK whose v3 signature proves a rotation lineage descending from the installed key. This is why a Play Store app cannot be updated with an APK someone re-signed, and why a debug build never installs over the release build of the same app.

What this page checks before a byte is uploaded

Each package is opened and read locally: the app's label, package name, version name and code, minSdkVersion and targetSdkVersion, the runtime permissions it will ask for, and the signing certificates. Then the phone is asked what it already has under that package name, and the two are compared — "10.2.1 → 10.3.0, upgrade", "older than what is installed, needs the downgrade flag", "needs API 33, this phone is API 30". The signature comparison uses the hash Android's own dumpsys package prints for each installed certificate, computed here from the APK's certificate; when a device does not print that line the page says the signature **could not be compared**, which is not the same as saying it matched. The split table lists every APK in the container with a verdict and a reason — matched your preferred ABI, superseded by a better one, nearest density, language you do not use — and you can override any of it, with a warning about what usually happens when you do.

Coming from another direction: the Web ADB Toolkit hub has the device dashboard and a drop zone for a quick single-APK install, the APK Analyzer opens the same files in far more depth with no phone attached, and the Android Debloater removes what you no longer want.

Frequently asked questions

How do I install an .apks, .xapk or .apkm file?

Drop it on this page with a phone connected over USB. Those three formats are ZIP archives holding a base APK plus config splits, and they cannot be installed by handing the whole archive to `pm install` — the installer needs each inner APK written into one session with `install-create` / `install-write` / `install-commit`. This page unzips the container, reads its `toc.pb` / `manifest.json` / `info.json`, chooses the splits matching your phone's CPU ABI, screen density and languages, and writes exactly those into a single session.

What does INSTALL_FAILED_UPDATE_INCOMPATIBLE mean?

An app with the same package name is already installed, but it was signed with a different certificate, so Android will not treat your APK as an update to it. It is not fixable with a flag. Either uninstall the installed copy first — its data goes with it — or get a build signed with the same key. It is the single most common failure when installing an APK downloaded from a mirror over an app that came from the Play Store, because the mirror's copy and the store's copy are frequently signed differently.

Why does my .apks fail with INSTALL_FAILED_INVALID_APK or MISSING_SPLIT?

Almost always because the set of splits going into the session is wrong. `MISSING_SPLIT` means a config or feature split was installed without the base it belongs to, or the base was installed while the app requires a feature module. `INVALID_APK` in a split install usually means the session contained two splits for the same dimension — two ABIs or two densities — which the framework refuses. Both are what the split table on this page exists to prevent: it installs one split per dimension and always includes the base. If you overrode the selection, that warning was about this.

Can I install an APK from a PC without installing adb?

Yes — that is what this page is. WebUSB lets a Chromium browser speak the ADB protocol to a phone with USB debugging enabled, so there are no platform-tools to download, no PATH to set and no commands to remember. The constraints are real, though: it is desktop Chrome, Edge or Opera only (Firefox and Safari have no WebUSB, and no phone browser can do it), and only one program at a time can claim the ADB interface, so a desktop `adb` server that is already running has to be stopped with `adb kill-server` first.

How do I downgrade an app to an older version?

Turn on the downgrade flag (`-d`) before installing. Android refuses a lower version code by default with `INSTALL_FAILED_VERSION_DOWNGRADE`, and the reason it does is worth respecting: the app's stored data was written by the newer version, and older code frequently cannot read a database it has never seen a migration for. A downgrade that installs cleanly can still leave the app crashing on launch or silently losing content. Uninstalling first and installing the old version fresh is the predictable route, at the cost of the data.

Does installing this way trigger Play Protect or void anything?

It can trigger Play Protect: the package verifier scans sideloaded APKs and can refuse one, which shows up as `INSTALL_FAILED_VERIFICATION_FAILURE`. That is a setting on the phone ("Scan apps with Play Protect", plus "Verify apps over USB" in Developer options), not something this page can or should turn off for you. Installing an APK does not modify the system partition, does not require an unlocked bootloader and does not root anything, so it is not in the category of actions that affect a warranty — but a work profile or a device-owner policy can forbid it outright, which surfaces as `INSTALL_FAILED_USER_RESTRICTED`.

  • Web ADB Toolkit

    The device dashboard and the rest of the ADB tools.

  • APK Analyzer

    Open an APK with no phone attached: permissions, signature, DEX and resources.

  • APK Extractor

    The other direction: pull an installed app's APK and splits back off the phone.

  • Android Debloater

    Remove preloaded apps over USB, with one-click restore.