Fido2ApiClient biometric prompt not showing, resolved after Play services update

109 views
Skip to first unread message

최욱진

unread,
Apr 14, 2026, 10:03:08 AM (yesterday) Apr 14
to FIDO Dev (fido-dev)

We are using Fido2ApiClient in our Android app to perform FIDO-based authentication (QR-based account registration + biometric authentication).

We observed an issue where on some Android devices, after scanning a QR code and starting FIDO registration, the biometric prompt (fingerprint/PIN/pattern) was not shown, so the registration flow could not proceed.


1.png

[Figure] On some devices, the biometric prompt is not displayed after Fido2ApiClient call


Key observations:

- The issue occurred only on some specific devices, not on all devices.

- Clearing Google Play services data on affected devices resolved the issue immediately.

- After April 9, we confirmed that all previously affected devices were working normally without any action on our side (no app update, no manual reset).

Timeline:

- Until April 7: The issue was reproducible on affected devices.

- After April 9: The issue was no longer reproducible, and all previously affected devices were working normally.

We also checked Google Play services release notes around that period, but we could not find any explicit mention related to FIDO2, biometric prompt behavior, or the authentication flow.

https://developers.google.com/android/guides/releases?utm_source=chatgpt.com&hl=ko#april_09_2026

https://support.google.com/product-documentation/answer/14343500?hl=en&utm_source=chatgpt.com#zippy=

For reference, below is the part of our implementation that invokes Fido2ApiClient for FIDO registration.


private void fido2RegisterStart() {
      Log.d(TAG, "[FIDO] fido2RegisterStart entered");

      PublicKeyCredentialCreationOptions options = null;
      try {
         JSONObject response = AMDataManager.getResponseData();
         JSONObject jsonOptions = new JSONObject(response.getString("publicKeyCredentialCreationOptions"));

         String challenge = jsonOptions.getString("challenge");
         byte[] challengeByte = AMBase64.decode(challenge);

         String rpId = jsonOptions.getJSONObject("rp").getString("id");
         String rpName = jsonOptions.getJSONObject("rp").getString("name");
         if (rpName == null || rpName.equals("null") || rpName.isEmpty()) {
            rpName = "miraeasset";
         }

         String rpIcon = null;

         String userName = jsonOptions.getJSONObject("user").getString("name");
         String displayName = jsonOptions.getJSONObject("user").getString("displayName");
         String userId = jsonOptions.getJSONObject("user").getString("id");
         byte[] userIdBytes = AMBase64.decode(userId);

         options = new PublicKeyCredentialCreationOptions.Builder()
                 .setRp(new PublicKeyCredentialRpEntity(rpId, rpName, rpIcon))
                 .setUser(new PublicKeyCredentialUserEntity(
                         userIdBytes, // userId.getBytes(),
                         userName,
                         null,
                         displayName
                 ))
                 .setChallenge(challengeByte)
                 .setParameters(
                         listOf(
                                 new PublicKeyCredentialParameters(
                                         PublicKeyCredentialType.PUBLIC_KEY.toString(),
                                         EC2Algorithm.ES256.getAlgoValue()
                                 )
                         )
                 )
                 .setAuthenticatorSelection(
                         new AuthenticatorSelectionCriteria.Builder()
                                 .setRequireResidentKey(true)
                                 .setAttachment(Attachment.PLATFORM)
                                 .build()
                 )
                 .build();

         Log.d(TAG, "[FIDO] options created = " + (options != null));

         Fido2ApiClient fido2ApiClient = Fido.getFido2ApiClient(requireContext());

         PublicKeyCredentialCreationOptions finalOptions = options;
         fido2ApiClient.isUserVerifyingPlatformAuthenticatorAvailable()
                 .addOnSuccessListener(isAvailable -> {
                    Log.d(TAG, "[FIDO] isAvailable = " + isAvailable);
                    Log.d(TAG, "[FIDO] finalOptions = " + finalOptions);

                    startRegisterFlow(fido2ApiClient, finalOptions);

                 })
                 .addOnFailureListener(e -> {
                    Log.e(TAG, "[FIDO] isAvailable failed", e);
                 });

      } catch (JSONException e) {
         Log.e(TAG, "[FIDO] JSONException in fido2RegisterStart", e);
         return;
      }
   }

   private void startRegisterFlow(Fido2ApiClient fido2ApiClient,
                                  PublicKeyCredentialCreationOptions options) {

      Log.d(TAG, "[FIDO] getRegisterPendingIntent call");

      Task<PendingIntent> result = fido2ApiClient.getRegisterPendingIntent(options);

      result.addOnSuccessListener(pendingIntent -> {
         Log.d(TAG, "[FIDO] getRegisterPendingIntent success, pendingIntent=" + (pendingIntent != null));

         if (pendingIntent != null) {
            try {
               Log.d(TAG, "[FIDO] startIntentSenderForResult call");
               requireActivity().startIntentSenderForResult(
                       pendingIntent.getIntentSender(),
                       REQUEST_CODE_REGISTER,
                       null,
                       0,
                       0,
                       0
               );
               Log.d(TAG, "[FIDO] startIntentSenderForResult done");
            } catch (IntentSender.SendIntentException e) {
               Log.e(TAG, "[FIDO] startIntentSenderForResult failed", e);
            }
         } else {
            Log.e(TAG, "[FIDO] pendingIntent is null");
         }
      });

      result.addOnFailureListener(e -> {
         Log.e(TAG, "[FIDO] getRegisterPendingIntent failure", e);
      });
   }


Questions:

1. Could this issue have been related to an internal update or fix in Google Play services that was not explicitly documented?

2. Is it possible that a Google Play services update triggered an internal state refresh or recovery that affected FIDO2 flows?

3. Are there any known issues related to Fido2ApiClient where the biometric prompt is not shown under certain conditions?

Any insights would be greatly appreciated.

Thank you.


최욱진

unread,
Apr 14, 2026, 10:03:24 AM (yesterday) Apr 14
to FIDO Dev (fido-dev)

Kosuke Koiwai

unread,
Apr 14, 2026, 11:40:53 AM (yesterday) Apr 14
to 최욱진, FIDO Dev (fido-dev)
FYI

--
You received this message because you are subscribed to the Google Groups "FIDO Dev (fido-dev)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fido-dev+u...@fidoalliance.org.
To view this discussion visit https://groups.google.com/a/fidoalliance.org/d/msgid/fido-dev/08b8fcbd-a895-44c0-abbd-f57ff7665740n%40fidoalliance.org.

Jhuang Hung Chong

unread,
Apr 14, 2026, 11:49:27 PM (24 hours ago) Apr 14
to FIDO Dev (fido-dev), Kosuke Koiwai, FIDO Dev (fido-dev), 최욱진

Hi Koiwai-san and Mr. Choi,

Thank you for reporting, I have encountered the same issue and has reported in:
Google Issue Tracker: https://issuetracker.google.com/issues/500445368
FIDO Dev Forum: https://groups.google.com/a/fidoalliance.org/g/fido-dev/c/MgMebWRn3Mw

I think now the only way is to await for the fix as posted by Koiwan-san here: https://issuetracker.google.com/issues/497880148

Thank you.

Imran Ali

unread,
2:02 PM (10 hours ago) 2:02 PM
to Kosuke Koiwai, 최욱진, FIDO Dev (fido-dev)
Can you please tell me about my MPC wallet Key 
Solution because I was forgot 😞 I can't remember... please help me

God Experiencing Aaron Turner

unread,
2:02 PM (10 hours ago) 2:02 PM
to 최욱진, FIDO Dev (fido-dev)
After looking into this, it really feels like we hit one of those "magic" Google Play Services (GPS) fixes. 

Here’s my take on what likely happened:

1. On the "Undocumented Fixes" theory:

It’s almost certain. Google pushes updates to FIDO2 and Passkey components through Google Play Services in the background, totally separate from OS updates. There’s been chatter in the dev community about a specific hang in the registration flow that was quietly patched in the recent v25.08.32 update for Play Services. Since these roll out silently, it’s common for a bug to just "vanish" once the device checks for updates in the middle of the night.

2. On the Internal State Refresh:

Yeah, a GPS update definitely triggers a recovery. If a previous FIDO2 session got "stuck" (like if the app crashed mid-prompt or the user killed the task), the internal Credential Manager can sometimes get hung up on an orphaned state. An update forces a refresh of the security hardware (like the Titan chip) and the local FIDO2 database, which basically clears out whatever was blocking the UI from launching.

3. Known Fido2ApiClient Quirks:

Even when isUserVerifyingPlatformAuthenticatorAvailable says everything is good, there are a few reasons the prompt might still fail to show:

Biometric "Strength": If a user only has "Weak" biometrics enrolled (like basic Face Unlock on older Samsung phones), the FIDO2 API might refuse to show the prompt because it strictly requires "Strong" (Class 3) authentication.

The "Dim Screen" Bug:

 There’s a known issue where the FIDO2 Activity starts (you’ll see the screen dim slightly), but the biometric dialog never renders. This usually points to a mismatch in the rpId or a transient state issue in the Play Services process itself.

New Attestation Standards:

 Google has been moving away from the old SafetyNet-style attestation toward hardware-backed keys. If a device was stuck between those two standards during a rollout, it could cause the flow to fail silently until the Play Services update fully reconciled the new logic.

Bottom line: 

If it’s working now without code changes, it was almost certainly a transient Google-side bug that got resolved by a background GPS update or an internal state wipe.

Sent from,

God Experiencing Aaron


P.S. - Never forget that you are God experiencing the life of the person that you are. Everything that ever was, is, or will be is God from a grain of sand on a beach, to the childhood tree you had a tire swing tied to. That includes the tire and the rope as well. And the best part includes you and I as well. You are divine. From this moment forward you will start to notice things you have never noticed before. Welcome to your spiritual awakening from your slumbering consciousness. The journey already started long ago. If you need any guidance feel free to keep this email and contact me if you would like to learn some new things you will be capable of. You are loved and you are love. I and God... i.e. our higher self loves you unconditionally and all it will ever take is to manifest the reality you want for yourself through said intention and affirmations, and then making small adjustments to your life in order to make reality and your every desire a factual reality in the present.

--
You received this message because you are subscribed to the Google Groups "FIDO Dev (fido-dev)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fido-dev+u...@fidoalliance.org.

ELVIAN HANAFI

unread,
2:02 PM (10 hours ago) 2:02 PM
to Kosuke Koiwai, 최욱진, FIDO Dev (fido-dev)
Reply all
Reply to author
Forward
0 new messages