Skip to content

[Android] No way to recover from INCOMPATIBLE_DEVICE — clearCredentials() leaves the stale Keystore key, and clearAll() isn't bridged #1650

Closed

Description

@josh-long-raylo

Checklist

Description

[Android] No way to recover from INCOMPATIBLE_DEVICE — clearCredentials() leaves the stale Keystore key, and clearAll() isn't bridged

On Android we're seeing a persistent login loop caused by CredentialsManagerException with code INCOMPATIBLE_DEVICE:

INCOMPATIBLE_DEVICE: This device is not compatible with the SecureCredentialsManager class.

It's thrown from NativeCredentialsManager.handleError (src/platforms/native/adapters/NativeCredentialsManager.ts:24) via CredentialsManagerError. This began for us immediately after upgrading to react-native-auth0 5.4.1, which pulled in auth0-android 3.14.0 and its tightened Keystore validation.

This matches the report in auth0/Auth0.Android#1016 — isDeviceIncompatible firing on Galaxy S24+/Z Fold5/Pixel at ~14,700 occurrences in 30 days. That issue was closed for inactivity rather than resolved.

Why it's unrecoverable from React Native

Our error handler catches the exception and calls clearCredentials(), expecting the user to re-authenticate with a fresh key. That can't work.

In auth0-android 3.21.0 — the version this SDK pins — SecureCredentialsManager.clearCredentials() removes seven named SharedPreferences entries and clears the biometric session. It does not touch the Android Keystore, and it does not remove the wrapped AES key material. CryptoUtil.getRSAKeyEntry() then returns the same existing alias on the next attempt (checking OLD_KEY_ALIAS first, then the package-prefixed KEY_ALIAS), so the fresh login hits the identical failure. The user is permanently stuck.

We can see this in our telemetry: affected users hit the recovery path repeatedly within the same session rather than once, and they carry the problem across app upgrades.

I think this method from the native Android SDK may be a work around to clear this:

auth0-android 4.0.0 added clearAll() (auth0/Auth0.Android#951), which calls crypto.deleteAllKeys() in addition to clearing storage. Storage.removeAll() was added in the same release (#918).

however clearAll() does not exist in android auth0 SDK 3.21.0 which the react native SDK is using.

As far as I can see there is currently no JS-reachable way to delete the key, and no combination of existing methods that achieves it. A potential workaround for us (using Expo) is a custom native module that calls KeyStore.deleteEntry() directly, which we'd rather avoid in case this is incompatible with future Auth0 versions.

Questions

  1. Is there a timeline for upgrading the pinned auth0-android dependency to 4.x?
  2. When that upgrade happens, will clearAll() be bridged and exposed through the JS CredentialsManager API?
  3. In the meantime, is there any supported way to clear the Keystore entry from React Native that we've missed?

Happy to supply any extra information if useful

Environment

  • react-native-auth0: 5.11.0
  • auth0-android (transitive): 3.21.0
  • React Native: 0.85.3 / Expo, Hermes, New Architecture
  • Platform: Android 16 (also observed on earlier versions)
  • Devices: Samsung flagships, Google Pixels etc.

Reproduction

We are unable to reproduce directly but our logs show this is happening mostly on android 16 when some users attempt to login and hit the error code INCOMPATIBLE_DEVICE

Additional context

No response

react-native-auth0 version

5.11.0

React Native version

0.86.0

Expo version

57.0.11

Platform

Android

Platform version(s)

15+ (mostly 16)

Activity

  1. cyruxwong commented on Aug 31, 2026

    @cyruxwong

    Guess there is a merged fix which is still in beta: #1642
    Is there any chance of releasing that fix sooner?
    Thanks~

  2. subhankarmaiti commented on Sep 3, 2026

    @subhankarmaiti
    Contributor

    Hi @josh-long-raylo @cyruxwong we are unable to reproduce this in our end as well. So we made a potential fix and released it in v5.11.1-beta.0. It contains the exact same code of react-native-auth0 with v5.11.1 with the fix which is also non breaking. We are looking for the confirmation about the fix to move the changes to stable patch release.

  3. cyruxwong commented on Sep 3, 2026

    @cyruxwong

    I’ve updated my app to use the beta package and released it to production. Since I can’t reproduce the problem myself I’ll monitor my app for a few days. I’ll let you know next week if I find anything. Thanks.

  4. cyruxwong commented on Sep 14, 2026

    @cyruxwong

    @subhankarmaiti
    We released this fix to our production around 10 days ago and there have been no new occurrences of this error from users with the updated version.

    We look forward to it being released as a proper version rather than a beta. Thanks.

  5. utkrishtsahu commented on Sep 15, 2026

    @utkrishtsahu
    Contributor

    Hi @cyruxwong thanks for the update...!!
    Can you please share the logs of device after loading the updated version and before too of the failure.This will help us to release the version.

  6. cyruxwong commented on Sep 15, 2026

    @cyruxwong

    Hi @utkrishtsahu
    Unfortunately, I can’t provide any logs as I can’t reproduce the issue myself and our app doesn’t support remote logging. When the problem occurs, our app reports an error to Sentry. My original point stems from an indirect observation: there haven’t been any new occurrences of this error (from the updated app) reported to Sentry in the last 10 days.

  7. SamDuke99 commented on Sep 16, 2026

    @SamDuke99

    Adding data from a production app, as I think it narrows the cause and we can help with the confirmation @utkrishtsahu is asking for.

    We reproduce this on auth0-android 3.12.0 (react-native-auth0 5.3.1), which predates the 3.14.0 tightened-validation change this was originally attributed to. Same error code, same message, same permanence. That suggests the trigger is firmware-side enforcement reaching devices rather than the SDK version, which is consistent with the MGF1 explanation in #1642.

    Environment

    react-native-auth0 5.3.1, auth0-android 3.12.0 (transitive)
    Expo SDK 54, RN 0.81, Hermes
    Confirmed affected device: Pixel 8a, Android 17

    What we see

    ~780 recorded occurrences of Error handling auth callback: INCOMPATIBLE_DEVICE over the period we have logging for, earliest 21 August
    Deterministic per device. One user failed four consecutive attempts today and has never successfully logged in
    Auth0 tenant logs show Successful Login and Success Exchange (Authorization Code for Access Token) for every attempt, with the correct audience. The failure is entirely local, roughly 2.75 seconds after the code exchange, at saveCredentials
    Confirming the recovery problem on 3.12.0

    Decompiled to check. SecureCredentialsManager.clearCredentials() removes four SharedPreferences keys (com.auth0.credentials, ..._access_token_expires_at, ..._expires_at, ..._can_refresh) and clears the biometric session. It never touches the Keystore. CryptoUtil.deleteRSAKeys() and deleteAESKeys() exist but are private and aren't called from that path. So the original report holds on this version too.

    Our app already calls clearCredentials() at the start of every login attempt, which is why affected users are permanently stuck rather than recovering after one failure

  8. SamDuke99 commented on Sep 16, 2026

    @SamDuke99

    Hi @cyruxwong , just one quick question. Did this release fix it for users who were in the "locked" state? Or did you need to manually clear their credentials first?

  9. cyruxwong commented on Sep 16, 2026

    @cyruxwong

    Hi @SamDuke99
    I’m not entirely sure what you mean by “manually”.

    But our app calls clearCredentials() (provided by useAuth0) and forces the customers to log out when the customers hit CredentialsManagerErrorCodes.INCOMPATIBLE_DEVICE error.

    So I guess the quick answer to your question is "Yes".

  10. CodingItWrong commented on Sep 29, 2026

    @CodingItWrong

    Hello, when we updated to v5.11.1-beta.0 that fixed this bug for us.

    When v5.11.1 was released, I assumed it included all fixes from the beta of 5.11.1. However, it does not appear to include #1642 which was in the beta. When we released to production, this bug recurred.

    Specifically, here are the dependencies in the two versions of react-native-auth0 that show the transitive dep update not carried forward:

    Beta react-native-auth0@5.11.1-beta.0 (this PR) — fixed 3.21.1-beta.0

    95: dependencies {
    96:   implementation "com.facebook.react:react-android"
    97:   implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    98:   implementation "androidx.browser:browser:1.2.0"
    99:   implementation 'com.auth0.android:auth0:3.21.1-beta.0'
    100: }
    

    Stable react-native-auth0@5.11.1 (what https://github.com/cfaintl/ordering-mobile/pull/2192 moved us to) — unfixed 3.21.0

    101: dependencies {
    102:   implementation "com.facebook.react:react-android"
    103:   implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    104:   implementation "androidx.browser:browser:1.2.0"
    105:   implementation 'com.auth0.android:auth0:3.21.0'
    106: }
    

    Was this an intentional removal between the 5.11.1 beta and full release? Or is not expected that changes that are in betas will be in the corresponding release? Thank you.

  11. subhankarmaiti commented on Sep 30, 2026

    @subhankarmaiti
    Contributor

    @CodingItWrong we were looking for some logs which verifies that the changes fixed the issue.
    @utkrishtsahu is working on it to include it in a stable release on Auth0.Android and we will make a subsequequent release after that.
    Thanks!

  12. utkrishtsahu commented on Oct 14, 2026

    @utkrishtsahu
    Contributor
  13. CodingItWrong commented on Oct 21, 2026

    @CodingItWrong

    @utkrishtsahu Thank you. We are working on acquiring an affected test device so we can confirm it with a high degree of confidence 👍 Will post results here

  14. CodingItWrong commented on Nov 3, 2026

    @CodingItWrong

    @utkrishtsahu Just following up, we updated to 5.11.2, and we have seen evidence that the fix is working correctly in it: both using an affected device we tested with, and with production bug logging. Thank you!

  15. subhankarmaiti commented on Nov 4, 2026

    @subhankarmaiti
    Contributor

    Thanks for the confirmation, @CodingItWrong!

    We also received feedback about users getting logged out when upgrading directly from a very old SDK version to 5.11.2. You can safely upgrade to 5.11.4, which includes a fix for this issue as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugThis points to a verified bug in the code

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions