Independent tech desk · no vendor sponsorshipPractical answers, not release notes
Numix Desk for the Linux desktop, open source and the machines we use every day

AndroidDecode A Document

Android App Won't Install: Signature, Play Protect and Storage Errors Decoded

The error string mapped to the actual cause, with the logcat filter that confirms it

OnePlus Nord smartphone displaying Android home screen
Photo: Gannu03 / Wikimedia Commons · CC BY-SA 4.0

When an Android app refuses to install, you can't use the 'App not installed' error string alone to diagnose the problem. Instead, delve into the specific PackageManager return codes to discover the actual issue causing the failed installation attempt.

Android's installer implementation, baked into the PackageManager, handles app installation, including installing, downgrading, updating or processing files. Some common reasons:

INSTALL_FAILED_ALREADY_EXISTS -1 The PackageManager documents this Android PackageManager code for installing a package that is already on the device. When you try to install an app that already exists on the device, you will see this error.

INSTALL_FAILED_UPDATE_INCOMPATIBLE -7 This error code indicates that the app's signatures do not match the currently installed version. The PackageManager documents this code to refer to a package whose signatures do match the currently installed version. This can happen if the developer's development certificates (they should be the same for all installations, for either production or debugging/demo) do not match.

INSTALL_FAILED_NO_MATCHING_ABIS -113 Android PackageManager, documents this Android PackageManager code used when the package manager service finds that native code does not match any ABI supported by the system. This can occur for cross-platform or prepackaged apps, which may ship binaries for multiple architectures.

INSTALL_FAILED_INSUFFICIENT_STORAGE -4 This Android PackageManager code is distinct from other errors generated during the installation of an app. While it is often ill-diagnosed as a simple case of the "storage being full" error, in reality this is announced by the package manager service when it finds insufficient storage. This code does not prove that it is free space alone.

Sometimes you will not see this error message but instead lack of permissions. However, an app will fail to install when the required permissions are missing. The affected device may show a message about the failure.

Signature and update conflicts

Apps can fail to install when they find evidence that an older version is already installed, or a build with a different signature. Upon reaching that point, there are two specific failure codes:

INSTALL_FAILED_ALREADY_EXISTS -1 The PackageManager throws this when the already-installed app has the same version name as the one in the APK. The solution is to reinstall using the reinstall. The developer may need to be informed about the push failure.

INSTALL_FAILED_UPDATE_INCOMPATIBLE -7 The PackageManager sends this when the signatures don't match the signatures of the already-installed app. That disallows on-device updates, downgrades, or reinstalls. Either the versionName metadata or the app's signing key (or both) must be the same as the already-installed version. Some firms default to the versionCode sequence as the versionName stream when they first create the build.gradle file, but they must update that before the first build.

ABI, archive, and package validity

When you are installing cross-platform code, such as a Flutter project, or deploying a monolithic APK that includes multiple architectures, the Android PackageManager looks for native code matching its defined ABIs, as described in this Android documentation on native support, and an error results when no code matches for the installed device. Or, a split-apk of the same app that does contain native code may fail only for one variant.

Here the exact error codes are:

INSTALL_FAILED_INVALID_APK -2 This one catches any kind of structural error in the APK file, whether missing required directories, from the discrepancies introduced by a misconfiguration, or any kind of corruption that sneaked in from an unclean build environment. Sometimes fixing the directory and file structure is sufficient. Occasionally an entire rebuild is needed, or even tests against a minimal environment. Here it is an archive error, always pointing to the file, and not needed to keep walking back up to the master to resolve.

INSTALL_FAILED_NO_MATCHING_ABIS -113 This is related to INSTALL_FAILED_INVALID_APK, as that can also pop up on cross-platform builds when some platforms sneak in incompatible APKs that an enabled filter should nudge out. Consider a team that added support for a feature -- the adapter code may look correct, but the APKs may have a bug in the build process. Then when pushed out to other developers' devices, installation goes awry. Testing with adb logcat filters can help here, as it can pull precise error codes from the fly-by, leaving a trail in the logs.

Storage that is not just storage

If the device runs out of space, it will definitely block the installation of an app. However, whether the storage is so limited is not the only check that triggers storage-based installation failures.

Here, we are using the verified fact:

INSTALL_FAILED_INSUFFICIENT_STORAGE This Android PackageManager code is distinct from other errors generated during the installation of an app. While it is often ill-diagnosed as a simple case of the "storage being full" error, in reality this is announced by the package manager service when it finds insufficient storage. This code does not prove that it is free space alone.

What log output can confirm

While checking the device logkit output and watching the prior commands could show a valuable output, I could not find in the documentation when to confirm the error codes using this tool.

The color line traces the sequence of commands from

The documentation doesn't provide a direct diagnostic for this PackageManager's behavior.

Instead, the sorted adb logs pick up the substring after the key phrase, cmd. In the final log file there is an Android/installerror/ code, followed by the app name. This breakpoint can be a valuable debugging tool.

Using this sorted log to grep for installing apps will give us the error code immediately. Herein there is no substring for the API level.

However, this DEBUG log does not have code to handle signature checks, so the warning on its own won't reveal why a signed app failed to launch on a rooted device.

Edge cases and non-install blocks

INSTALL_FAILED_ABORTED -115 While unlikely without direct interference, an aborted installation leaves the same generic message. Many times the testers don't take care to remove all traces of incomplete installs from their test device, which can cause this.

INSTALL_FAILED_VERSION_DOWNGRADE -25 The PackageManager throws this on a manual install, preventing a higher version number from replacing a lower one. It may be time to burn in the artifacts directory for each multi-arch build.

INSTALL_FAILED_CPU_ABI_INCOMPATIBLE -6 For some Android Project Android Studio has the Android version field as a mandatory feature when starting a project. We could make this non-mandatory if you remove some code.This error confirms there is an issue.

INSTALL_FAILED_SHARED_USER_INCOMPATIBLE Maybe there is an error in one of the dependencies, but not enough to abort, so it gets past that point.

The message you don't want to see indicates that the check-in process for the artifacts failed. Validating them can tell you that the APK build can be trusted for use on a device. However, try to leave a margin of space in case of expansion.

This looks like the App not installed error, but in some circumstances, when an app is incorrectly packaged, that can cause this message to occur too.

If you're deploying an app to a device, it may return this error due to any of the above reasons, but instead look for an issue in the packaging.Then install the same app on Android or run it on an emulator.

More from the desk