Get your free and exclusive +30-page Authentication Analytics Whitepaper

Native App Passkey Errors: Ultimate Overview (2026)

Native app passkey errors differ drastically between iOS and Android. Learn what breaks, why Android is 3-5x worse and how to measure it.

Vincent Delitz

Vincent

Created: March 5, 2026

Updated: March 5, 2026

Blog-Post-Header-Image

1. Introduction#

When deploying native apps at large scale with passkeys, difficult problems start appearing that cannot be anticipated. Why is it so difficult to deploy passkeys in native apps?

StateOfPasskeys Icon

Want to find out how many people use passkeys?

View Adoption Data

The most important matter: code cannot be changed once deployed. One version will often stay available for a long period. The second matter: diagnosing problems is difficult - you can't easily inspect what's happening inside the user's device. The third matter: the environment is constantly changing and extremely heterogeneous - your app runs across dozens of OS versions, hundreds of device models, multiple authenticator configurations and varying network conditions, all shifting independently while your code stays frozen.

What this article covers vs related articles:

In this article we answer the following questions:

  • What can break - We take apart what can break in a native environment and what it encompasses
  • How to measure - How should you measure native implementation of passkeys?
  • Mitigation - What measures should you take to protect your native application?
Key Facts
  • Native apps give better error signals than web. Using preferImmediatelyAvailableCredentials on iOS and Android, native apps can distinguish "no credential available" from "user cancelled" - a signal web browsers deliberately hide.
  • Android is 3-5x worse than iOS. Median abort rates are ~10-14% on Android native vs ~2-3% on iOS native. Budget Android devices can reach 75-90%.
  • Code is immutable once deployed. Unlike web, you cannot hotfix a shipped native app version. Error handling bugs persist for months until users update.
  • Events and outcomes are different layers. An "abort" is a classifier outcome that can mean technical failure, user cancel or missing tracking. You need both outcome-level KPIs and event-level error logs to act.
  • The implementation choice determines the error surface. Native implementations surface platform-specific error codes (ASAuthorizationError, Credential Manager exceptions). WebView implementations surface web DOMExceptions.
  • Android's internal error codes are invisible to web browsers. GPS compresses 50+ specific failure modes into 12 generic WebAuthn types before Chrome sees them. Native apps can parse the raw error messages to identify root causes. See the full GPS passkey error codes reference.
  • Android fragmentation compounds the reliability problem. It is not the quality - it is diversity. A fragmented OS version distribution across thousands of device models, combined with different credential provider stacks (Google Password Manager vs Samsung Pass vs third-party managers), means a single app ships into dozens of behaviorally distinct environments simultaneously.
  • Don't apply iOS thresholds to Android. A 5% abort rate on iOS may signal a bug. The same 5% on Android flagship devices is excellent.

2. Passkeys in native Apps#

Your implementation architecture determines which error surface you're dealing with. There are three primary approaches, each producing a different class of errors. For full implementation guidance, see Native App Passkeys: Native vs. WebView Implementation.

Native ImplementationSystem WebViewEmbedded WebView
iOS APIASAuthorizationController + ASAuthorizationPlatformPublicKeyCredentialProviderASWebAuthenticationSession / SFSafariViewControllerWKWebView
Android APICredentialManager + CreatePublicKeyCredentialRequest / GetCredentialRequestChrome Custom Tabsandroid.webkit.WebView (AndroidX WebKit 1.12.1+)
Error surfacePlatform-specific codes: iOS ASAuthorizationError domain codes (see Apple passkey error codes), Android [50xxx]-prefixed GPS error messages + Credential Manager exception types (see GPS passkey error codes)Web DOMExceptions (NotAllowedError, AbortError, etc.)Web DOMExceptions + native config failures (AASA, Digital Asset Links)
"No credential" signalClean - preferImmediatelyAvailableCredentials returns distinct "no credentials"Hidden behind opaque NotAllowedErrorHidden behind opaque NotAllowedError
Config failure modesAASA / assetlinks.jsonNone (runs in browser context)AASA / assetlinks.json + WebKit version + feature detection
Error guideThis articleWebAuthn Errors guideBoth guides apply

Many production apps combine approaches: attempt native login first with preferImmediatelyAvailableCredentials for instant authentication, then fall back to System WebView when no credential is available. This combination is where the error classification in this article becomes most relevant - you need to handle both native error codes and web DOMExceptions in the same flow.

The following discussion focuses on native implementation errors for Android and iOS. This analysis applies whenever you implement either operation:

  • WebAuthn Get - Login with a credential
  • WebAuthn Create - Create a new credential

3. Environment#

Understanding errors in native apps requires tracking the full environment context. Unlike web browsers where you control the update cycle and users run mostly recent versions, native apps face a dramatically more complex matrix. Your immutable code runs across a constantly shifting landscape of OS versions, hardware capabilities and authenticator states.

3.1 Environment Dimensions#

The environment for a native passkey implementation consists of eight independent dimensions that all vary simultaneously:

ComponentiOS ExampleAndroid ExampleWhy it matters
OS VersioniOS 16 to iOS 26Android 13 to Android 16API availability changes (e.g. ASAuthorization behaviors differ between iOS versions, Credential Manager changes)
App Versionv2.1.0, v2.2.0, v2.3.1 all activev3.0.1, v3.1.0, v3.2.4 all activeBugs shipped in one version persist for 6-12 months until users update. Multiple versions run simultaneously in production
Device BrandAppleSamsung, Google, OnePlus, Xiaomi, OppoManufacturer customizations affect WebAuthn behavior. Samsung has different biometric stack than Pixel. Some brands ship heavily modified Android
Device ModeliPhone 16, iPhone 17 Pro, iPhone 17 Pro Max (Face ID)Pixel 9/10 Pro, Samsung S24 (SM-S921B), Galaxy A15 (SM-A156E), OPPO CPH2695Biometric hardware affects error patterns. Low-end devices have unreliable sensors. Specific models have known quirks
Authenticator StatusiCloud Keychain enabled/disabled, sync status, iCloud signed inGoogle Password Manager enabled, Play Services version, third-party providers registeredAvailability unpredictable.
Default / Preferred AuthenticatoriOS 17+: iCloud Keychain or third-party (1Password, Dashlane) if selected in SettingsAndroid 14+: Google Password Manager or third-party (Bitwarden, 1Password) if registered and activeThird-party providers can be installed but deactivated. Operations fail differently when preferred provider unavailable vs when feature not supported pre-iOS 17/Android 14. Some manufacturers disable third-party support entirely
Device ProtectionPasscode required, Face ID enrolled, Touch ID enrolled, passcode-only mode, biometric lockoutPIN/Pattern/Password required, fingerprint enrolled, face unlock enrolled, screen lock only, biometric lockoutPasskeys require device protection configured (passcode/PIN/gesture OR biometric). If neither configured, passkeys not supported. Lockout state affects which errors surface

3.2 Android Diversity Problem - why Android breaks more than iOS#

The environmental complexity described above creates dramatically different outcomes on Android vs iOS. Android's extreme heterogeneity makes it 3-5x more susceptible to passkey implementation failures compared to iOS in production environments.

3.2.1 Error Rate Distribution by Platform#

When measuring abort rates across native passkey implementations, the distribution consistently reveals the Android diversity problem across virtually every deployment we have data or reports on:

PlatformBest CaseMedian
iOS Native0-3% (flagship models, recent iOS)2-3%
Android Native0-2% (Pixel, premium OPPO/Motorola)10-14%

Key insight: The worst iOS device performs better than the median Android device. iOS maintains consistency across its ecosystem because Apple controls both hardware and software. Android's open ecosystem creates massive variance.

3.2.2 Brand-Level Performance Variance#

Android error rates cluster strongly by manufacturer, revealing how deeply customization affects reliability:

Manufacturer TierTypical Abort RangeReason
Google Pixel3-15%Stock Android, tight Credential Manager integration, consistent hardware
Premium Android (Samsung S-series flagship)8-12%Manufacturer customization balanced with quality control
Budget Android (Samsung A-series)20-40%Cost-optimized hardware, unreliable biometric sensors
Low-tier Budget (ZTE, vivo budget)75-90%Credential Manager implementation effectively broken on some models

For comparison, iOS devices cluster tightly around 2-5% regardless of model, with outliers only appearing on very old hardware (iPhone 8/X era) running outdated iOS versions.

3.2.3 Authentication Method Gap#

Device protection type amplifies the Android fragmentation problem:

PlatformBiometric AuthPIN/Code AuthCode Penalty
iOSbaseline1.5-2x worsemoderate degradation
Androidbaseline2-3x worsesevere degradation

Why this matters: On Android budget devices, PIN/code authentication can push abort rates from 30% to 60%+. The same operation on iOS might go from 3% to 6% - still usable.

3.2.4 Manufacturer Customization Impact#

The root cause is architectural:

iOS: Apple controls the entire ASAuthorization stack. iCloud Keychain integration is identical on iPhone 16 and iPhone 17 Pro. Updates are synchronized. Biometric hardware (Face ID, Touch ID) is standardized per generation.

Android: Manufacturers customize everything:

  • Samsung's biometric stack differs from Google's
  • Some manufacturers (OnePlus, Xiaomi, Oppo) ship heavily modified Android builds
  • Google Play Services version variance affects Credential Manager availability
  • Budget device manufacturers optimize for cost, not reliability
  • Third-party provider support is optional - manufacturers can disable it entirely

This means an error on a Samsung Galaxy A15 running Android 15 tells you nothing about what will happen on a Pixel 9 running the same Android version. The codepaths are different.

3.2.5 Practical Implications for Error Classification#

When you see high abort rates:

On iOS:

  • Likely a code bug (your implementation is broken)
  • Or user behavior pattern (users actually canceling - ASAuthorizationErrorCanceled code 1001)
  • Or environmental issue (iCloud Keychain disabled/not signed in - surfaces as ASAuthorizationErrorFailed code 1004 wrapping an internal "Cannot create a passkey. iCloud Keychain is off." error, or the new ASAuthorizationError.deviceNotConfiguredForPasskeyCreation code 1010 on iOS 26+)

On Android:

  • Could be code bug
  • Could be user behavior
  • Could be manufacturer customization breaking Credential Manager
  • Could be budget device with broken biometric hardware
  • Could be OS version too old for stable Credential Manager
  • Could be device manufacturer disabled third-party provider support
  • Could be Google Play Services version incompatibility

Bottom line: Don't use the same error rate thresholds for Android and iOS. A 5% abort rate on iOS might indicate a problem. The same 5% on Android flagship devices is excellent. On Android budget devices, anything under 30% is acceptable. For testing these device-specific behaviors systematically, see Testing Passkey Flows in Native iOS & Android Apps.

WhitepaperAuthenticationAnalytics Icon

Authentication Analytics Whitepaper:
Track passkey adoption & impact on revenue.

Get Whitepaper

4. What actually breaks in native Passkey Flows#

If you want to diagnose passkey issues in native apps, you need to separate where the failure happened from how it was classified later.

The following diagram shows the full lifecycle of a native passkey registration (create) operation. The flow applies to both Android (Credential Manager → TEE) and iOS (ASAuthorizationController → Secure Enclave). Each numbered step represents a boundary where failures can occur - from the app through the OS framework, down to secure hardware and back to the server:

In practice, native WebAuthn failures happen in five stages:

StageWhat happensTypical failure sourceBest telemetry signal
Pre-authenticatorBuild request, fetch challenge/options, fetch tokenAPI/network/serialization/state issuesUnexpected error events with pre-authenticator context
Authenticator invocationSystem sheet/dialog is shown and user/device respondsUser cancel, no credential, platform/provider exceptionPlatform error codes: Apple passkey error codes (iOS), GPS passkey error codes (Android), WebAuthn errors (browsers)
Post-authenticatorServer-side verification / finish callBackend rejection, timeout, transport failuresServer-side error codes from verification endpoint
User intent pathUser declines the passkey path in app UIProduct UX choice, not technical failureAbort tracking in your analytics
App crashAuthenticator response handling crashes the appUnhandled exception during credential parsing, malformed response, threading issueCrash reporting (e.g. Crashlytics, Sentry) correlated with passkey operation

On both platforms, the authenticator invocation stage is where native apps have a decisive diagnostic advantage over web browsers. Both Apple and Google compress dozens of specific internal error codes into a small set of public error types before they reach your app - and browsers lose even more detail on top of that. Native apps that log the raw platform errors can distinguish root causes that browsers collapse into generic NotAllowedError.

On Android, GPS generates 50+ internal error codes that are compressed into 12 WebAuthn types. Native apps can parse the [50xxx] prefixed error messages to identify specific failures like Folsom sync key decryption (error 50162) that Chrome reports as generic NOT_ALLOWED_ERROR. For the complete error code reference, architecture diagrams and androidx.credentials error handling guide, see GPS Passkey Error Codes: the complete Reference.

On iOS, Apple compresses ~22 internal error codes into 11 public ASAuthorizationError codes. Native apps receive dedicated codes for common failures (1001 for user cancel, 1005 for no credentials, 1010 for device not configured) that Safari collapses into generic DOMExceptions. For the complete error code reference, translation mapping and Swift error handling guide, see Apple Passkey Error Codes: the complete Reference.

iOSAndroid
Internal error codes~22 (ASCAuthorizationError 0-22)50+ (GPS codes 50100-50196)
Public error codes11 (ASAuthorizationError 1000-1010)12 WebAuthn ErrorCode enum values
Key diagnostic mechanismlocalizedDescription / NSUnderlyingErrorKey on code 1004[50xxx] prefix in error message string
Platform trendApple extracting specifics from generic 1004 each iOS releaseGoogle migrating FIDO2 path → Credential Manager path
Browser information lossSafari translates to ~3 DOMException typesChrome pattern-matches on 5 known message strings
Full referenceApple passkey error codesGPS passkey error codes

Beyond these stages, two behavioral patterns are critical to detect:

Authentication loop detection: When the authenticator invocation fails and error handling is incorrect, the app can enter a retry loop - repeatedly invoking the authenticator, crashing or failing each time. This is especially dangerous in native apps because the user has no way to break out except force-closing the app. At Corbado, we detect these loops server-side by tracking repeated failed attempts from the same session within a short time window. A loop pattern (3+ failed attempts within a few minutes) is a strong signal that the app's error handling is broken on that specific device/OS combination.

Authentication avoided by device change: When a user consistently authenticates on one device but suddenly switches to another (e.g. moving from native app to web browser, or from one phone to another), this often signals a problem. The user is actively working around a broken passkey flow on their primary device. Tracking device-change patterns after failed authentication attempts reveals which device/OS/version combinations are silently pushing users away from passkeys - even when no error was reported.

Debugger Icon

Want to experiment with passkey flows? Try our Passkeys Debugger.

Try for Free

5. How Corbado can help#

Without dedicated tooling, teams typically discover native passkey problems reactively - a support ticket spike, a sudden drop in login conversion or a vague "passkeys don't work on my phone" report. By the time you investigate, the damage is done: users have churned, fallback flows have been triggered silently and the root cause is buried in aggregate metrics.

Corbado's passkey analytics platform continuously monitors device-level passkey health across your entire user base - both for passkey creation and passkey login. Instead of waiting for complaints, you see which device models are failing, how error rates trend over time and whether a new OS update or GPS version introduced regressions. Effective native passkey analytics needs two layers working together: outcomes that tell you "how bad is the user impact?" and events that tell you "what is technically failing?" - the sections below walk through both. For the full analytics framework, see Passkey Analytics and the Authentication Analytics Playbook. The screenshots below show sample data from a demo environment for illustration purposes.

5.1 Device Health Monitoring for Passkey Creation#

The first layer of monitoring is the device health view for passkey creation. This surfaces the "top offenders" - device models with the highest abort rates during passkey registration - ranked by error percentage and with per-device event counts for statistical confidence.

On iOS, the dashboard immediately reveals patterns that would take weeks to discover manually: older devices stuck on iOS 16 (iPhone 8 Plus, iPhone X, iPhone 8) cluster at the top with 20%+ abort rates, while modern devices on iOS 18+ sit around 10-12%. The Block button lets you suppress passkey creation prompts for specific device cohorts where the failure rate is unacceptable - Passkey Intelligence then skips passkey creation entirely on those devices instead of leading users into a dead end.

Substack Icon

Subscribe to our Passkeys Substack for the latest news.

Subscribe

5.2 Error Classification for deep Investigation#

Device health tells you where things break. The error classification view tells you what is breaking - grouping individual errors into named patterns with counts, rates and trend indicators.

This is where you move from "Android has a higher abort rate" to actionable engineering work. The trend percentages are the key signal, here just some exemplary sample data in production there are over 100 classifications: While the top pattern (authenticator timeout) is declining at -9%, the iOS native unknown errors are growing at +25% and Android native at +37%. A Bitwarden Chrome extension bug has spiked +205% - likely triggered by a recent extension update. The same drill-down workflow applies to any pattern in the list - the native iOS and Android errors visible here work exactly the same way. We follow the Bitwarden spike below because it had the largest trend change, but investigating a native ASAuthorizationError or Credential Manager failure uses the same path. Clicking into any pattern opens a detailed view where you can analyze how the error developed over time, see it in context of total login volume and inspect individual error samples:

Error pattern detail: Bitwarden Chrome extension bug trend over time

The error trend chart shows the Bitwarden extension bug spiking in November before declining again - correlated against total login volume (dashed line) to distinguish real regressions from traffic fluctuations. The samples table at the bottom surfaces the exact event type, error message, OS and browser for each occurrence, giving engineers everything they need to reproduce and fix the issue.

5.3 Drilling into a single Process#

From any error sample you can open the full process detail view - the individual authentication process with its complete context, subprocesses and event timeline.

This example shows a user on Windows 10 with Chrome 145. The client capabilities section at the top confirms the browser supports ConditionalCreate - a WebAuthn feature that silently creates a passkey during a password login, upgrading the user without prompts. The process contains four subprocesses: two login attempts and two append (passkey creation) attempts. The second append failed with two errors - both flagged as append-error-unexpected. Drilling into the events reveals one is a clientPasskeyOperationErrorSilent (the silent conditional create failed with a non-cancel error) and the other is a cboApiNotAvailablePostAuthenticator (API error after passkey creation). Both errors are already automatically pattern-matched to "bug in Bitwarden Chrome extension" - Corbado recognized the signature from prior occurrences. Despite the errors in the second append, the fourth subprocess eventually completed successfully with Bitwarden as the credential provider.

What makes this view powerful is the context available per error. You see the failure not as an isolated log line but as a snapshot of the complete authentication state at the moment it happened:

ContextWhat it tells you
Existing passkeysWhich credentials the user already has, on which providers
Password managersInstalled credential providers (Bitwarden, 1Password, Google Password Manager) and their state
Platform & OS versionWindows / macOS / iOS / Android, exact version (from client hints, not just user agent)
Browser & versionChrome, Safari, Firefox - including discrepancies between user agent and client hints
WebAuthn capabilitiesConditionalCreate, ConditionalUI, Hybrid, PPKA, UVPA - what the device actually supports
Subprocess flowFull sequence of login and append attempts within the process, with outcomes per step
Event timelineEvery event with timestamps, error types, messages and automatic pattern matches

This explains far more than log files ever could - you can immediately correlate a failure with "this user has Bitwarden installed, no platform passkey, and the conditional create was attempted after a successful password login." That is the bridge between outcomes ("abort rate is up") and events ("conditional create fails on Windows Chrome 145 with a Bitwarden extension bug") - without this level of drill-down, a spike in your abort dashboard stays an abstract number; with it, you go from "something is broken" to a reproducible bug report in minutes.

The natural next step is to zoom out from a single process into the full user history. The user search view adds another layer of context:

ContextWhat it tells you
Client environmentsEvery distinct environment the user logged in from - different browsers, devices, incognito sessions. One user can have multiple client environments over time
Client environment lifetimeTimeline showing when each environment was first and last seen, how the user's account behaves over weeks or months
Classification per environmentEach client environment gets its own passkey health classification and score - one environment can be append-completed while another is missing-pk-support
Swim lanes per deviceSide-by-side timeline of processes across environments, revealing parallel device use and whether a user switched devices after a failure
Passkey and password manager stateWhich credentials exist on the account, which providers are active and when they were registered

This level of context is where patterns like "authentication avoided by device change" from section 4 become visible - but the user search workflow is a topic for a separate article.

Enterprise Icon

Get free passkey whitepaper for enterprises.

Get for free

6. Conclusion#

Native passkey deployments are harder than web. Your code is immutable once shipped, Android's fragmentation creates a 3-5x reliability gap compared to iOS and the error surfaces differ across platforms, OS versions and credential providers. Without visibility into what is actually breaking, teams discover problems reactively - weeks after users have already churned.

The debug walkthrough in section 5 shows what changes with the right tooling: a device health spike leads to an error classification, the classification leads to a trend chart, the trend chart leads to a single process with full context - existing passkeys, password managers, capabilities, the complete subprocess flow. You go from "abort rate is up" to a reproducible bug report in minutes, not weeks.

The operational discipline that follows is straightforward: block device cohorts where passkeys reliably fail, track error pattern trends to catch regressions before they impact conversion and set different thresholds for iOS and Android based on each platform's baseline. Treat passkey reliability as a continuous operational capability, not a one-time feature launch.

For the complete web browser error reference (DOMException names, error messages by browser engine), see WebAuthn Errors in Production. For platform-specific internal error code references, see GPS Passkey Error Codes (Android) and Apple Passkey Error Codes (iOS). For testing these patterns on real devices, see Testing Passkey Flows in Native iOS & Android Apps. For setting up your analytics framework, see Passkey Analytics.

Igor Gjorgjioski Testimonial

Igor Gjorgjioski

Head of Digital Channels & Platform Enablement, VicRoads

Corbado proved to be a trusted partner. Their hands-on, 24/7 support and on-site assistance enabled a seamless integration into VicRoads' complex systems, offering passkeys to 5 million users.

Passkeys that millions adopt, fast. Start with Corbado's Adoption Platform.

Start Free Trial

Add passkeys to your app in <1 hour with our UI components, SDKs & guides.

Start Free Trial

Share this article


LinkedInTwitterFacebook