App Isn't Compatible With Your Phone: targetSdk, ABI, minSdk
On this page
Short answer: “App not installed as app isn’t compatible with your phone” is one message for several different refusals. On current Android versions the usual causes are a targetSdkVersion that is too low (Android 14 blocks below 23, Android 15 and later below 24), native libraries only for an ABI the phone does not run (typically 32-bit only on a 64-bit-only phone), a minSdkVersion above the phone’s Android version, or a required shared library the phone does not have. adb install prints the exact INSTALL_FAILED_* code, and each code has one fix in your build settings.
This guide reproduces each cause with small APKs I built, installs them on an Android 14 (API 34) and an Android 16 (API 36) emulator, and shows the real output. It then checks the same files with this site’s APK & AAB analyzer, which reads the manifest and native libraries in your browser without uploading anything.
Who this is for: developers who ship their own APK outside a store, or test builds by hand, and get this message from a user or a test device.
What you will learn:
- How to get the real failure code with adb
- Four causes, each reproduced, with the code it produces
- Which of them the analyzer flags, and which you read from its tables
- Where to change the setting in Gradle, Flutter and Unity
- What REA, the open-source project by morluto, adds in version 6.4.0, and what it does not
Only test builds you own or are authorized to examine, on devices you control.
Step 1: Get the real error code
The phone hides the reason. Connect the device (or start an emulator) and install from a computer:
adb install app-release.apk
These are the results I got with the sample APKs. Every APK has package dev.example.compat and is signed with my release key. Only one setting changes each time.
| Sample | What is wrong | Android 14 (API 34) | Android 16 (API 36) |
|---|---|---|---|
compat-target22.apk |
targetSdkVersion 22 |
INSTALL_FAILED_DEPRECATED_SDK_VERSION |
INSTALL_FAILED_DEPRECATED_SDK_VERSION |
compat-target23.apk |
targetSdkVersion 23 |
Success | INSTALL_FAILED_DEPRECATED_SDK_VERSION |
compat-armv7-only.apk |
only lib/armeabi-v7a/ |
INSTALL_FAILED_NO_MATCHING_ABIS |
INSTALL_FAILED_NO_MATCHING_ABIS |
compat-x86_64-only.apk |
only lib/x86_64/ |
INSTALL_FAILED_NO_MATCHING_ABIS |
INSTALL_FAILED_NO_MATCHING_ABIS |
compat-min35.apk |
minSdkVersion 35 |
INSTALL_FAILED_OLDER_SDK |
Success |
compat-missing-library.apk |
required <uses-library> absent |
INSTALL_FAILED_MISSING_SHARED_LIBRARY |
INSTALL_FAILED_MISSING_SHARED_LIBRARY |
compat-watch-feature.apk |
requires android.hardware.type.watch |
Success | Success |
compat-fixed.apk |
target 36, min 24, arm64-v8a + armeabi-v7a + x86_64 | Success | Success |
Both emulators are arm64 images that report ro.product.cpu.abilist as arm64-v8a only, with no 32-bit ABI. Recent Pixel phones are also 64-bit only.
The full failure lines say a lot on their own:
Failure [INSTALL_FAILED_DEPRECATED_SDK_VERSION: App package must target at least SDK version 23, but found 22]
Failure [INSTALL_FAILED_DEPRECATED_SDK_VERSION: App package must target at least SDK version 24, but found 23]
Failure [INSTALL_FAILED_NO_MATCHING_ABIS: INSTALL_FAILED_NO_MATCHING_ABIS: Failed to extract native libraries, res=-113]
Failure [INSTALL_FAILED_OLDER_SDK: Requires newer sdk version #35 (current version is #34)]
Failure [INSTALL_FAILED_MISSING_SHARED_LIBRARY: Reconciliation failed...: Reconcile failed: Package dev.example.compat requires unavailable shared library dev.example.missing.library; failing!]
The first two lines came from the API 34 and the API 36 emulator respectively, which shows the floor moving from 23 to 24. On my emulators, logcat did not record these failures, so the adb output is the place to read them.
Step 2: Check the APK in your browser
Open the APK & AAB analyzer and choose the Outside Play (sideload) scenario, or Both. The install-time rule SIDE-01 is grouped under sideloading, and PLAY-04 under Google Play, so Both shows each of them. Then drop the APK.
What the analyzer reported for the samples (asOf 2026-10-14):
compat-target22.apk
SIDE-01 fail reject targetSdkVersion=22
Android 15+ requires targetSdkVersion >= 24
Android 14+ requires targetSdkVersion >= 23
note: Installation fails on Android 14 and later (INSTALL_FAILED_DEPRECATED_SDK_VERSION).
PLAY-01 fail reject targetSdkVersion=22, required: >= 36 (phone/tablet, since 2026-08-31)
compat-target23.apk
SIDE-01 fail reject targetSdkVersion=23, Android 15+ requires targetSdkVersion >= 24
note: Installation fails on Android 15 and later (INSTALL_FAILED_DEPRECATED_SDK_VERSION).
compat-armv7-only.apk
PLAY-04 fail reject lib/armeabi-v7a/ present, lib/arm64-v8a/ missing
SIDE-01 matched both emulators exactly: target 22 failed on both, target 23 only on Android 16.
Three causes are not separate checks. You read them from the report:
- x86_64 only. PLAY-04 flags a 32-bit ABI without its 64-bit counterpart and an
.sowhose ELF header does not match its folder. An APK whose only folder islib/x86_64/passes both, and every check oncompat-x86_64-only.apkpassed. The Native libraries table shows the problem: one row, ABIx86_64, ELF64-bit x86-64. A phone with an ARM CPU cannot use it. Make surearm64-v8ais in that table. - minSdk. The Summary shows
minSdk. Compare it with the Android version of the phone (API 34 is Android 14, 35 is Android 15, 36 is Android 16). No check flags a high minSdk, because a high minSdk is a valid choice. - Required libraries. The current version does not list
<uses-library>entries in a table. Open Manifest → Raw XML and look foruses-librarywithandroid:required="true".
Step 3: Read the phone’s side
You need the phone’s API level and ABI list to compare. With plain adb:
adb shell getprop ro.build.version.sdk
adb shell getprop ro.product.cpu.abilist
With REA 6.4.0, inspect-adb-device reads a fixed set of build properties, including both values:
export REA_ADB_PATH="$HOME/Library/Android/sdk/platform-tools/adb"
rea inspect-adb-device emulator-5582 --format json
From normalized_result.properties on the API 34 emulator:
ro.build.version.release 14
ro.build.version.sdk 34
ro.product.cpu.abilist arm64-v8a
ro.product.model sdk_gphone64_arm64
rea list-adb-features <serial> lists the device’s declared features (pm list features), which helps with the Play filtering question below.
REA cannot report the install failure code itself. rea install-adb-package installed the good samples, but each failed install came back as a generic unreadable_output error, with no INSTALL_FAILED_* text. The 6.4.0 code reads Failure [...] from adb’s standard output, and the adb 37.0.1 I used prints it to standard error and exits with code 1. Keep plain adb install for this step.
Step 4: Fix it in your build
targetSdkVersion too low (DEPRECATED_SDK_VERSION)
Raise targetSdk. Android 14 refuses below 23 and Android 15 and later refuse below 24 (Android 15 behavior changes). Don’t stop at the floor: Google Play requires 36 for phone and tablet apps since 2026-08-31 (PLAY-01), and the install floor has risen twice in two Android releases.
android {
defaultConfig {
minSdk = 24
targetSdk = 36
}
}
Raising the target changes runtime behavior (permissions, background limits, intents), so test the new version, don’t just rebuild it. In Flutter, the values come from android/app/build.gradle(.kts) (often flutter.targetSdkVersion, set by your Flutter SDK version). In Unity, set Target API Level in Player Settings → Other Settings.
adb install --bypass-low-target-sdk-block installs an old-target build anyway. My target-22 sample installed with it on both emulators. It is a developer flag for testing legacy builds on a device you control. Users don’t have it, and it does not fix the APK.
No matching ABI (NO_MATCHING_ABIS)
Ship arm64-v8a for phones. Keep x86_64 if you test on x86_64 emulators, and add armeabi-v7a only for older 32-bit devices:
android {
defaultConfig {
ndk { abiFilters += listOf("arm64-v8a", "armeabi-v7a", "x86_64") }
}
}
Watch for an abiFilters that was set for the emulator and never changed, and for an SDK that only ships 32-bit .so files. In Flutter, release builds include the arm64 libraries by default. Check any --target-platform flag in your build script. In Unity, choose IL2CPP and tick ARM64 under Target Architectures. ARM64 is not available with the Mono backend. A Unity build with only ARMv7 fails on 64-bit-only phones in exactly this way.
The compat-fixed.apk sample with three ABIs installed on both emulators. If you also publish on Play, run the 16 KB page size check on the 64-bit libraries.
minSdkVersion too high (OLDER_SDK)
Either the phone is too old for the build, or minSdk was raised by accident, often because a dependency requires it and the manifest merger took the higher value. If you meant to support the phone, lower minSdk and replace whatever forced it up. If you didn’t, the message is correct. Tell users the minimum Android version.
Missing shared library (MISSING_SHARED_LIBRARY)
A <uses-library android:required="true"> names a library that this phone does not have, for example a vendor or OEM library. If your app can run without it, set android:required="false" and check for it at runtime. Otherwise ship a build variant without it.
uses-feature: not an installer check
My sample that requires android.hardware.type.watch installed on both phone emulators with adb install. In my test, <uses-feature> did not block installation. Google Play and some stores use it to filter which devices can see the app. If users report “not compatible” on a store page, compare your required features with rea list-adb-features output from an affected device, and set android:required="false" for anything optional.
FAQ
The message says “isn’t compatible”, but adb says something else.
Then follow adb. If the code is INSTALL_FAILED_UPDATE_INCOMPATIBLE, you are looking at a signing conflict with an installed copy. See package conflicts with an existing package.
Can a 64-bit phone run my 32-bit-only APK?
Only if the phone still lists a 32-bit ABI (check ro.product.cpu.abilist). Many current phones don’t, and both of my emulators failed with NO_MATCHING_ABIS. Ship arm64-v8a.
The app has no native code. Can ABIs still be the problem?
No. With no lib/ folder there is nothing to match, so look at targetSdk, minSdk and libraries.
I received an AAB, not an APK. An AAB cannot be installed directly. Build APKs from it with bundletool, as shown in the AAB to APK guide.
Next steps
- Check targetSdk, ABIs and signing before you send a build: APK & AAB analyzer
- Signing conflicts with an installed copy: App not installed: package conflicts
- When it installs but crashes: adb logcat and bugreport with REA
- Reference: Android 14 behavior changes, Android ABIs, 64-bit requirement, REA’s DISCLAIMER.md