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.
Below, each cause is reproduced with small APKs I built and installed on an Android 14 (API 34) and an Android 16 (API 36) emulator, with the real output, then checked with this site’s APK & AAB analyzer, which reads the manifest and native libraries in your browser without uploading anything.
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
If you already use REA (a third-party open-source CLI), inspect-adb-device in 6.7.0 reads the same properties:
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
Don’t use rea install-adb-package to diagnose this error: in my runs every failed install came back as a generic unreadable_output error without the INSTALL_FAILED_* text (adb 37.0.1 prints Failure [...] to standard error). Keep plain adb install for Step 1.
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 adb shell pm list features on 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.
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.
It installs now, but crashes on launch.
That is a different problem: read the crash buffer with adb logcat -b crash -d, as in adb logcat crash and tombstone debugging.
References: Android 14 behavior changes, Android ABIs, 64-bit requirement.