Back to Blog

Fix INSTALL_FAILED_UPDATE_INCOMPATIBLE: signatures do not match

BetaDrop Team
6 min read
install_failed_update_incompatiblesignatures do not match previously installed versionadb install failed update incompatibleapk signature mismatch
Fix INSTALL_FAILED_UPDATE_INCOMPATIBLE on Android

Reviewed by Kaushal Rola

Founder, BetaDrop — we build the OTA tooling this post describes.

Share:

You built a new APK, ran adb install or sent the install link to a tester, and the install came back with:

adb: failed to install app-release.apk: Failure
[INSTALL_FAILED_UPDATE_INCOMPATIBLE: Existing package com.example.app
signatures do not match newer version; ignoring!]

On the phone itself the same refusal hides behind the generic “App not installed” dialog; the App not installed guide covers getting adb to name the error. This page picks up from there.

The file is not corrupt, and this is not a versionCode problem. Android found an app with the same package name already installed, compared the signing certificate inside the new APK with the certificate of the installed copy, and they are different. So it refuses the in-place update — every time, with no override.

What “signatures do not match” literally means

Every APK is code-signed, and Android treats an app’s identity as the pair of its package name and its signing certificate. An update is only an update if the same key signed it. Anything else is, as far as the platform can tell, a stranger trying to replace your app while keeping its name — which is exactly the attack the rule exists to stop. A signature mismatch is the anti-tampering model working, not breaking.

Two consequences follow. First, there is no adb flag, developer setting, or root-free workaround that makes a differently signed update install; the fixes below are the only honest routes. Second, the message tells you the certificates differ but not which two certificates, so the real debugging is finding out which keystore signed what. (Keystores and the v1–v3 signature schemes are covered in the Android app signing guide.)

The three ways teams hit it

A debug build over a release build, or the reverse

Android Studio signs every debug build with an auto-generated keystore at ~/.android/debug.keystore; your release APK is signed with the real release keystore. Install a release candidate on a phone still carrying the debug build — or hit Run in Android Studio against a device that has the release build on it — and the certificates differ.

CI signs with a different keystore than a teammate’s machine

The pipeline signs release builds from a keystore in its secret store; a developer builds “the same release” locally from a file on their own disk. And every machine generates its own debug keystore, so even two teammates’ debug builds cannot update each other. The tell is a build that installs cleanly on a fresh device but refuses to update anything a colleague or the pipeline installed earlier.

Google Play’s app signing key vs your upload key

With Play App Signing, the APK a phone downloads from the store is signed by Google, using the app signing key it holds. Your machine signs release builds with the upload key, which is normally a different certificate. Sideload your own release build over the Play-installed copy of your own app and Android refuses — correctly. Both builds are legitimately yours; they are still two different signers.

The fix ladder

1. Unblock the device: uninstall the installed copy

adb uninstall com.example.app

Or long-press the icon and uninstall on the device. This is the whole fix for the phone in front of you, and it has one real cost: the app’s local data goes with it — logins, settings, on-device databases. On your own test phone that is a shrug; on a tester’s personal device it may be a week of accumulated state, so warn them before asking, not after.

2. Fix the cause: one keystore per build path

One signing key per app, one source of truth for it. Keep the release keystore where CI and any human who cuts releases sign from the same file — a secret store, not five drifting copies. If teammates need to install over each other’s development builds, commit a shared debug keystore to the repo and point signingConfigs at it, so every machine produces the same signer; that is acceptable for a debug key precisely because it guards nothing.

3. Verify before you send: compare SHA-256 fingerprints

The whole error is two SHA-256 fingerprints failing to match, and you can compare them before anyone installs anything. Drop the new APK into the APK signature checker, note the SHA-256 line, then check the previous build the same way. It is a web page, so both sides of a mismatch can do it — no keytool, no apksigner setup, no Android SDK. The APK is read on our API and discarded when the parse finishes; nothing about it is stored. Same fingerprint: this error is not the one you are hitting — a matching signer still leaves the other refusals (a lower versionCode, a minSdk or ABI mismatch, no free space) that the App not installed guide ranks. Different: every tester holding the old build will hit this error, and you get to choose — fix the signing, or tell testers to uninstall — before the link goes out instead of after the complaints come back.

4. Diagnose: find out what signed the copy on the device

When you do not know where the installed build came from, ask the device:

adb shell pm list packages | grep -i example
adb shell dumpsys package com.example.app | grep -A 3 signatures

The first line confirms the exact package name; the second prints the package manager’s signing summary for it. For a full certificate readout, pull the installed APK off the device and inspect it like any other file:

adb shell pm path com.example.app
# package:/data/app/~~kR3f9A==/com.example.app-Xz1Qa2==/base.apk

adb pull "$(adb shell pm path com.example.app | grep -m1 base.apk | cut -d: -f2 | tr -d '\r')" installed.apk

Note the shape of what pm path prints: a full path, package: prefix and /base.apk included, so substitute the command rather than pasting its output into a path of your own. An app installed from Play as an app bundle prints several lines — the base APK plus its splits — and every split carries the same signer, so base.apk is the one to pull.

Run installed.apk through the same signature checker and you are reading both certificates side by side instead of guessing which two keystores the mismatch is between.

When the refusal is the right outcome

  • An “update” from outside the store, over a Play-installed app. If the installed app came from Google Play and the new APK came from a website or a chat message, the mismatch is Android protecting you or your tester from a look-alike. Do not work around it — get updates from the source the app came from.
  • Your local build over the Play copy on your own phone. Expected to fail, forever, because Google signs the store copy. Use a Play internal testing track when a build must update store installs, or accept the uninstall on dedicated test devices.
  • Hoping a distribution service will make it go away. None can. BetaDrop delivers the APK byte-for-byte as you signed it and does not re-sign builds; no host can make two differently signed APKs update each other, and a service claiming otherwise would need to hold your signing key.

Frequently Asked Questions

Can I force adb to install an APK over a signature mismatch?

No. There is no adb flag that overrides a signature check on a stock device. The -r flag replaces an app only when the certificates already match, and -d only relaxes version-code downgrades on debuggable builds. Uninstalling the existing copy is the only supported route, and that is deliberate: an override switch would turn every update into a hijacking opportunity.

Will users updating from Google Play ever see INSTALL_FAILED_UPDATE_INCOMPATIBLE?

Not from a normal store update. With Play App Signing, Google signs every build it delivers for your app with the same app signing key, so certificates always match from one Play update to the next. The error lives at the edges of the store instead: sideloading a build over a Play install, adb installs during development, or testers mixing store and non-store copies of the same app.

Does adb uninstall delete the app data, and can I keep it?

Yes, a plain adb uninstall removes the app together with its local data, and keeping the data does not help here. The pm uninstall -k variant preserves the data directory, but that directory stays owned by the old certificate, so a differently signed install is still refused and you end up uninstalling again without the flag. Preserved data only survives when the next install is signed with the same key, which is exactly the situation where this error never appears.

Is the APK signature scheme version (v1, v2, v3) the cause of this error?

No. The scheme version describes how a signature is stored in the file, not which key produced it, and Android compares keys. Two builds signed by the same keystore with different scheme versions still update each other fine. The one sanctioned way to change signing keys is v3 key rotation with an apksigner lineage, and even that has a limit: devices running Android 8 or older keep comparing against the original certificate.

In short

INSTALL_FAILED_UPDATE_INCOMPATIBLE means the new APK and the installed app were signed by different keys, and Android will not budge on that. Uninstall to unblock one device, align keystores to unblock the team, and make the thirty-second check part of shipping: run the outgoing build — and, when in doubt, the previous one — through the APK signature checker before any link goes out. When the fingerprints line up, upload the APK to BetaDrop and send testers one install link and QR code: same signer every build, and this error stays gone.

Ready to Distribute Your App?

Upload your IPA or APK file and get a shareable install link in seconds. No account required. Completely free.

iMobile Designs
Developed by iMobile Designs
Made with
in India