Get your free and exclusive +45-page Authentication Analytics Whitepaper
Torna alla panoramica

Guida definitiva agli errori WebAuthn in produzione (2026)

Scopri cosa significano i comuni errori WebAuthn come NotAllowedError in produzione e come classificarli per tipo di operazione, tempistiche e contesto.

Vincent Delitz
Vincent Delitz

Creato: 9 febbraio 2026

Aggiornato: 3 luglio 2026

Guida definitiva agli errori WebAuthn in produzione (2026)

Questa pagina è stata tradotta automaticamente. Leggi la versione originale in inglese qui.

1. Introduzione#

In produzione, gli errori WebAuthn sono fonte di confusione perché i browser espongono un set ridotto di nomi DOMException (come NotAllowedError) che possono rappresentare molteplici cause di fondo. Oltre a ciò, la stragrande maggioranza degli "errori" - spesso superiore al 95% nelle implementazioni su larga scala ottimizzate - rappresenta in realtà un comportamento previsto (l'utente ha interrotto la richiesta passkey del sistema operativo).

Debugger Icon

Sperimenta i flussi passkey nel Passkeys Debugger.

Prova gratis

Importante: per motivi di privacy, i browser non distinguono se l'utente ha annullato attivamente l'operazione o se non esisteva alcuna passkey. Tuttavia, in alcune situazioni e con abbastanza contesto, sia sul web che sulle piattaforme native, alcuni di questi casi possono essere differenziati utilizzando segnali come le tempistiche.

Se desideri le definizioni canoniche per questi nomi, inizia da MDN DOMException. Per le condizioni specifiche di WebAuthn che portano a queste eccezioni (e che i browser sono tenuti a far rispettare), consulta la Specifica W3C Web Authentication.

Se tratti tutti gli errori come "bug", farai le cose sbagliate:

  • inquinerei le tue metriche di errore con normali annullamenti
  • ti perderai regressioni reali nascoste all'interno della massa di NotAllowedError
  • pubblicherai un'interfaccia utente (UI) che confonde gli utenti anziché aiutarli a riprendersi

In questo articolo rispondiamo a:

  • Cosa significano solitamente i nomi degli errori WebAuthn più comuni nel traffico reale?
  • Come si disambigua NotAllowedError in bucket azionabili (annullamento vs timeout vs disponibilità)?
  • Perché lo stesso errore significa cose diverse a seconda dell'operazione (login con Conditional UI vs login modale vs creazione di passkey vs creazione condizionale)?
  • Quale contesto minimo dovresti acquisire in modo che "ha fallito" diventi un problema riproducibile?
Fatti chiave
  • NotAllowedError è un segnale di superficie, non una causa principale. Può significare annullamento, timeout, "nessuna credenziale locale" o attivazione utente mancante a seconda del contesto.
  • Il tipo di operazione cambia il significato. Lo stesso NotAllowedError significa cose diverse durante il login con Conditional UI, il login modale, la creazione manuale di passkey, la creazione condizionale e le aggiunte attivate automaticamente.
  • Le tempistiche dall'inizio dell'operazione sono il segnale più sottovalutato: immediato (<1s), annullamento dell'utente (1-15s) e timeout (30s+) sono categorie fondamentalmente diverse.
  • AbortError è solitamente un problema di ciclo di vita/concorrenza (navigazione, re-render, richieste multiple in corso).
  • SecurityError è quasi sempre legato a configurazione/contesto ed è raro nelle implementazioni di produzione mature.
  • I "nomi degli errori del browser" e i "rifiuti di verifica del server" sono livelli diversi. Tieni traccia dei rifiuti del server come codici espliciti, non come errori generici del client.
  • I nomi degli errori non elaborati non sono utilizzabili da soli. Acquisisci sempre il tipo di operazione, le tempistiche e il contesto della piattaforma insieme a error.name in modo da poter classificare gli errori in bucket che puoi effettivamente correggere.
  • "Ambiente" è più che semplice Browser + OS. Per comprendere veramente gli errori, devi tracciare l'intera combinazione: versione del sistema operativo, client (versione di browser/app), impostazioni dell'autenticatore (es. stato iCloud/GPM) e il modello hardware specifico.
  • Gli errori di login sono P1, gli errori di creazione sono P2. Mentre gli errori di creazione (P2) spesso hanno volumi maggiori a causa degli abbandoni degli utenti, gli errori di login (P1) bloccano l'accesso e richiedono avvisi immediati.

2. Un cheat sheet per la produzione#

Se hai solo bisogno di una mappatura rapida per sbloccare il debugging, inizia con questa tabella. È sbilanciata verso ciò che i team vedono effettivamente nelle dashboard e nei ticket di supporto.

error.nameCosa significa di solito in produzioneCosa controllare per confermarePrima azione (UX + ingegneria)
NotAllowedErrorFoglio ignorato dall'utente, timeout o mancata disponibilità raggruppati in un unico bucket. Questo è il bucket di errori più grande in produzione.time-to-error, se è apparsa l'interfaccia utente QR/ibrida, se la cerimonia è iniziata da un'azione utente realeTratta come previsto: ripristina UI + mostra fallback
AbortErrorLa tua app (o il browser) ha interrotto la cerimonianavigazione/re-render durante la cerimonia; chiamate WebAuthn concorrenti; AbortController.abort()Imponi una sola richiesta in corso; impedisci cambi di route; gestisci l'interruzione come normale flusso di controllo
SecurityErrorContesto/policy non consentitoorigine + strategia RP ID; iframe/embedding; HTTPS; feature policyCorreggi configurazione RP ID/origine; convalida le policy di embedding; assicurati che il contesto sia sicuro
InvalidStateErrorMancata corrispondenza dello stato (spesso registrazione duplicata)registrazione vs login; excludeCredentials; credenziale esistente sull'autenticatoreTratta come "già registrato"; adatta il percorso UX; correggi la generazione delle opzioni
ConstraintErrorI requisiti non possono essere soddisfattiauthenticatorAttachment, userVerification, requisiti delle resident keyRilassa i vincoli o fornisci un percorso/fallback alternativo. Esempio: blocco schermo mancante su Android
DataErrorGli input sono malformati/incoerenticodifica base64url; formati di id/challenge/user handleCorreggi codifica/serializzazione; aggiungi convalida nella generazione delle opzioni
NotSupportedErrorLa piattaforma/il browser non supporta ciò che hai richiestoversione di OS/browser; presupposti del rilevamento delle funzionalitàApplica subito un fallback; registra il segmento; evita di mostrare CTA per passkey in ambienti non supportati
UnknownErrorPiattaforma/autenticatore non riuscito in modo genericopicchi dopo aggiornamenti OS; build del dispositivo; problemi del provider del credential managerUX compatibile con i tentativi (retry); acquisisci numeri di build; indaga sui picchi del segmento

Una cosa facile da trascurare: lo stesso error.name può significare cose molto diverse a seconda del tipo di operazione. Tieni presente il contesto dell'operazione mentre leggi le sezioni seguenti. In pratica, gli errori di creazione di passkey (registrazione) superano in genere di gran lunga gli errori di login: la tabella precedente si applica a entrambi, ma la creazione è dove risiede la maggior parte del volume.

Successivamente, approfondiremo NotAllowedError perché è quello che vedrai di più e quello che i team fraintendono più spesso.

3. NotAllowedError: l'operazione è andata in timeout o non era consentita#

NotAllowedError spesso sembra che "le passkey abbiano fallito", ma di solito è la piattaforma che ti dice che l'utente non ha completato l'interfaccia utente del sistema operativo. La chiave è suddividerlo in bucket su cui puoi agire.

Cosa vedrai nella console del browser:

OrigineMessaggio di errore
Chrome, EdgeNotAllowedError: The operation either timed out or was not allowed. See: https://www.w3.org/TR/webauthn-2/#sctn-privacy-considerations-client.
Safari, WebKitNotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.
Safari, WebKitNotAllowedError: This request has been cancelled by the user.
Chrome, EdgeNotAllowedError: The operation is not allowed at this time because the page does not have focus.
Safari, WebKitNotAllowedError: The document is not focused.
FirefoxNotAllowedError: Operation failed.

Tutti questi emergono come error.name === "NotAllowedError". Il error.message differisce in base al motore del browser e alla causa sottostante, ma il risultato è lo stesso: la cerimonia non è stata completata.

Ciò si applica sia al login che alla creazione della passkey. Durante il login (Conditional UI, modale con o senza allowList), NotAllowedError in genere significa che l'utente non ha completato la cerimonia. Durante la creazione della passkey, lo stesso errore emerge per motivi diversi: l'utente ha chiuso la finestra di dialogo di creazione (la creazione condizionale non ha funzionato, o la pagina ha perso il focus durante un'aggiunta attivata automaticamente. Il tipo di operazione cambia il significato dell'errore e cosa dovresti fare al riguardo.

Le tempistiche sono spesso un segnale sottovalutato. Un errore dopo meno di un secondo da un clic di solito è un rifiuto immediato (l'ambiente non può farlo, il documento non è focalizzato, manca la capacità). Un errore dopo pochi secondi è un annullamento dell'utente (ha visto la finestra di dialogo e ha deciso di non procedere). Un errore dopo oltre 30 secondi è un timeout. Sulle piattaforme native, le tempistiche sono particolarmente importanti: i round-trip dell'autenticatore, i prompt biometrici e gli handoff del credential manager hanno tutti durate caratteristiche che ti aiutano a separare "non ha funzionato" da "l'utente si è allontanato". Non riesci ancora a distinguere facilmente se esisteva una passkey.

3.1 Disambiguare con il contesto#

Non hai bisogno di un segnale perfetto. Hai bisogno di un contesto sufficiente per evitare di trattare ogni NotAllowedError allo stesso modo. iOS/Safari riceve un'attenzione specifica di seguito perché ha vincoli unici (requisiti di attivazione dell'utente nelle versioni precedenti), ma nel volume di errori puro, Windows e i browser Chromium spesso generano più NotAllowedError di qualsiasi altra piattaforma. Questi segnali ti portano spesso all'80% del risultato:

SegnaleSignificato probabileCosa fare dopo
Errore immediato (<1s)Rifiuto dell'ambiente: nessuna capacità, documento non focalizzato, superficie di creazione condizionale non disponibileControlla il rilevamento delle funzionalità; assicurati che il documento sia in primo piano; verifica che l'operazione sia supportata su questa piattaforma
Annullamento rapido (1-3s)Prompt a sorpresa / nessun contestoCambia la tempistica del prompt; aggiungi un tempo di ricarica (cooldown) dopo l'annullamento
Annullamento con tempistiche dell'utente (3-15s)L'utente ha visto la finestra di dialogo e ha scelto di non procedereUX prevista; ripristina UI + mostra fallback
Timeout (30s+)La cerimonia è andata in timeout senza l'intervento dell'utenteInserisci nel bucket "non completato"; valuta se il prompt sia stato notato
Appare UI QR/ibrida prima del fallimentoNessuna credenziale locale disponibile su questo dispositivo. Nota: rilevare in modo affidabile le decisioni del codice QR prima che si verifichino richiede un livello di passkey intelligence che sappia se esiste una credenziale utilizzabile sul dispositivo attuale.Limita le offerte di passkey; rendi esplicito "Usa telefono"; riduci le sorprese con i QR
Concentrato su iOS/Safari e attivato senza un clic/toccoAttivazione utente mancanteAvvia la cerimonia da un vero gesto dell'utente
Durante conditional create o aggiunta attivata automaticamenteAutofill non disponibile, credenziale già esistente o pagina che ha perso il focus. Gli errori di conditional create possono apparire all'improvviso e ad alto volume quando la funzione viene lanciata, rendendo questa una delle fonti di errore più grandi durante la notte.Vedi conditional create; controlla lo stato di visibilità del documento; usa getClientCapabilities() per verificare il supporto a conditionalCreate prima di tentare la chiamata

Questo è anche il motivo per cui NotAllowedError dovrebbe essere raramente visibile all'utente. Non è un messaggio su cui l'utente può agire.

La classificazione del contesto è anche il punto in cui i tassi di successo si dividono più nettamente. L' Analisi del tasso di successo dell'autenticazione tramite passkey del Corbado Passkey Benchmark 2026 misura il completamento del primo trimestre 2026 al 55-95% per i flussi identifier-first su dispositivi sconosciuti rispetto al 95-99% per i ritorni su dispositivi noti in tutte le implementazioni B2C su larga scala. L'identifier-first web su iOS raggiunge un completamento dell'85-95% (% CDA 0–5%), web su Android al 70–85% (% CDA 5–10%) e web su macOS al 70–85% (% CDA 10–15%), mentre il web su Windows si attesta al 45-60% di completamento identifier-first con % CDA al 55-65% su Windows 11 e 40-55% su Windows 10. Leggere il volume di NotAllowedError senza separare i contesti di dispositivi noti rispetto a quelli sconosciuti confonde due regimi di successo fondamentalmente diversi.

Una sfumatura che conta in produzione: alcuni user agent potrebbero mostrare i timeout come TimeoutError, ma molti team vedono ancora i timeout raggruppati in NotAllowedError nelle dashboard. In ogni caso, tratta i timeout come "la cerimonia non è stata completata" e classificali usando tempistiche e contesto.

3.2 Gestione UX: rendi l'annullamento un'uscita normale#

Quando il foglio del sistema operativo viene ignorato o va in timeout, l'interfaccia utente dovrebbe riprendersi immediatamente e reagire in modo aggraziato. Un insieme pratico di regole:

  • ripristina la UI di login (nessun caricatore che continua a girare)
  • mantieni lo stato dell'identificatore (non forzare il reinserimento)
  • mostra un fallback visibile nella stessa schermata
  • evita banner spaventosi per risultati previsti

Oltre le basi:

  • Tratta la prima interruzione come normale e offri un nuovo tentativo con una spiegazione chiara. Solo dopo un secondo annullamento dovresti suggerire opzioni di fallback.
  • Consenti fino a tre richieste di creazione prima di un cooldown, in modo che gli utenti sorpresi abbiano una seconda possibilità.
  • Dividi i conteggi degli errori tra creazione e login in modo da confrontare elementi simili.
  • Segmenta i tassi di errore in base a sistema operativo, browser e dispositivo in modo da poter individuare dove risiede effettivamente l'attrito.

Se i tuoi "annullamenti" sono veramente alti, il passo successivo è correggere le cause principali alla loro base: tempistiche del prompt, sorprese sui codici QR e bassa disponibilità.

3.3 Correzioni ingegneristiche che riducono NotAllowedError#

Inizia con le modifiche che spostano rapidamente le metriche:

  • Correggi le tempistiche del prompt e l'attivazione dell'utente (soprattutto su iOS/Safari): eventi attivati dall'utente WebAuthn su Safari.
  • Riduci le sorprese con i QR/ibridi: perché i flussi passkey mostrano i codici QR e gli utenti abbandonano.
  • Gestisci le offerte in modo che le passkey vengano mostrate quando è probabile che abbiano successo: offri le passkey solo quando hanno un'alta probabilità di successo.
  • Utilizza modelli che evitano di inviare prompt quando non esiste alcuna credenziale locale: WebAuthn immediate mediation.
  • Gestisci le instabilità di rete: Gli errori di rete durante la verifica si manifestano spesso come guasti generici lato client. Implementa una coda offline per i log della tua telemetria, così non perdi i dati sugli errori quando la connessione dell'utente cade durante la cerimonia.
  • Limita le cerimonie con le API di rilevamento in modo che gli errori di ambiente non gonfino il tuo bucket NotAllowedError. Inizia con isUVPAA() come controllo più basilare, quindi usa getClientCapabilities() per controlli più precisi (creazione condizionale, get condizionale, trasporto ibrido, autenticatore di piattaforma). Tieni presente che le API di rilevamento possono interrompersi con gli aggiornamenti del sistema operativo: iOS 26.2 includeva un bug WebKit in cui isUVPAA() restituiva false su tutti i browser basati su WKWebView anche se le passkey funzionavano correttamente, causando improvvisi picchi di NotAllowedError per il 10-25% degli utenti iOS.

3.4 Nota sull'evoluzione dei nomi degli errori#

I nomi degli errori sono un bersaglio mobile. Ci sono proposte in corso per aggiungere errori WebAuthn più granulari (ad esempio, per separare "nessuna credenziale disponibile" da "l'utente ha annullato"). A partire da febbraio 2026, ciò non è implementato in nessun browser, quindi vale ancora la pena creare i propri bucket di motivazioni in base al contesto e alle tempistiche. Se desideri seguire questo lavoro, vedi WebAuthn issue #2062 e l' Spiegazione dei nuovi codici di errore.

I restanti nomi degli errori sono meno frequenti ma vale comunque la pena capirli quando appaiono.

4. AbortError: l'operazione è stata interrotta#

AbortError è raro in volume rispetto a NotAllowedError, ma quando appare è altamente diagnostico: di solito significa che la cerimonia non è terminata perché la tua app ha invalidato la richiesta (si è verificata una navigazione, lo stato è cambiato o è iniziata una seconda richiesta).

Cosa vedrai nella console del browser:

OrigineMessaggio di errore
Chrome, EdgeAbortError: The operation was aborted.
Chrome, EdgeAbortError: Aborted by AbortSignal.
FirefoxAbortError: signal is aborted without reason
FirefoxAbortError: Operation timed out.
Safari, WebKitAbortError: The user aborted a request.
ChromeAbortError: CredentialContainer request is not allowed.

Le cause comuni di produzione includono:

  • più chiamate WebAuthn simultanee (due prompt in competizione)
  • cambio di rotta/re-render durante una cerimonia in corso
  • chiamata a AbortController.abort() durante tentativi o pulizia dello stato

Per risolverlo, concentrati sul rendere la cerimonia una "sezione critica":

  • consenti solo una richiesta in corso alla volta
  • blocca la navigazione durante la cerimonia (o annulla in modo pulito e ripristina l'interfaccia utente)
  • tratta l'interruzione come previsto dal flusso di controllo: mostra un pulsante di riprova e un metodo di fallback

Se noti AbortError concentrato in superfici integrate o app multi-dominio, il bucket successivo da controllare è SecurityError.

5. SecurityError: WebAuthn non è supportato su siti con errori del certificato TLS#

SecurityError è il browser che ti dice: "questo contesto non è autorizzato a fare ciò che hai chiesto." In pratica è quasi sempre configurazione, non comportamento dell'utente. In implementazioni di produzione mature, SecurityError è raro perché questi problemi vengono in genere individuati durante i test di integrazione. Se compare in produzione, di solito significa che un nuovo dominio, contesto di integrazione o target di distribuzione è stato aggiunto senza un'adeguata configurazione WebAuthn.

Le cause più comuni includono:

  • Mancata corrispondenza di RP ID / origine (configurazioni multi-dominio)
  • Restrizioni sull'incorporamento cross-origin (iframe)
  • Contesto non sicuro (non HTTPS) o policy/autorizzazioni bloccate
  • .well-known/webauthn o .well-known/assetlinks.json mal configurati, mancanti o temporaneamente non disponibili. Problemi di rete durante la finestra critica in cui il browser recupera questi file causeranno errori. Un punto cieco comune: se la tua homepage è inattiva per manutenzione, anche i file well-known sono offline, interrompendo le cerimonie passkey tra tutti i relying party che ne dipendono.

Cosa vedrai nella console del browser:

OrigineMessaggio di errore
Chrome, EdgeSecurityError: WebAuthn is not supported on sites with TLS certificate errors.
Qualsiasi browserSecurityError: The relying party ID is not a registrable domain suffix of, nor equal to the current origin's effective domain.
Chrome (iframe)SecurityError: The 'publickey-credentials-create' feature is not enabled in this document.

In produzione, il SecurityError è raro: quasi sempre vengono rilevati durante i test di integrazione. Quando compaiono, l'errore del certificato TLS è il sopravvissuto più comune.

Il ciclo di debug più veloce è:

  • registra gli input di origine e RP ID che hai usato
  • riproduci nello stesso contesto (top-level vs iframe, dominio prod vs staging)
  • se incorpori il login, verifica che la policy delle autorizzazioni sia configurata (ad esempio publickey-credentials-create / publickey-credentials-get): MDN Permissions-Policy
  • verifica la strategia del tuo dominio
  • se utilizzi iframe, convalida le feature policy

Una volta gestito SecurityError, il prossimo bucket da prendere sul serio è il set di errori che spesso indicano bug di implementazione: InvalidStateError, ConstraintError e DataError.

PasskeysCheatsheet Icon

Cheatsheet Passkeys. Guide pratiche, pattern di distribuzione e KPI per programmi passkey.

Ottieni la cheatsheet

6. InvalidStateError, ConstraintError, DataError: tratta come bug di implementazione#

Questi errori dovrebbero essere rari in un'implementazione passkey matura. Quando compaiono, in genere indicano che la generazione delle opzioni è errata per un segmento o che il flusso è nello stato sbagliato.

6.1 InvalidStateError: "credenziali già registrate con il relying party"#

Cosa vedrai nella console del browser:

OrigineMessaggio di errore
Safari, WebKitInvalidStateError: The user attempted to register an authenticator that contains one of the credentials already registered with the relying party.
Chrome, EdgeInvalidStateError: At least one credential matches an entry of the excludeCredentials list in the platform attached authenticator.
Chrome, EdgeInvalidStateError: A request is already pending.
FirefoxInvalidStateError: An attempt was made to use an object that is not, or is no longer, usable

Significati tipici:

  • registrazione: hai tentato di creare una credenziale che esiste già (duplicata)
  • login: meno comune; spesso significa che il flusso/stato è incoerente per la piattaforma

Gestione pratica:

  • se avviene nella registrazione manuale, trattalo come "già registrato" e indirizzalo di conseguenza
  • assicurati che excludeCredentials elenchi tutti gli ID delle credenziali esistenti per l'utente, così l'autenticatore può rilevare i duplicati
  • durante il conditional create, InvalidStateError è previsto e dovrebbe essere ignorato silenziosamente: significa che esiste già una passkey nel provider. Lo stesso vale per NotAllowedError e AbortError durante il conditional create (vedi conditional create on Chrome)

6.2 ConstraintError#

Significato tipico: l'autenticatore non può soddisfare i vincoli richiesti.

Cause scatenanti comuni:

  • blocco schermo del dispositivo mancante (soprattutto su Android): la piattaforma richiede la verifica biometrica o del PIN ma il dispositivo non ha una schermata di blocco configurata
  • requisiti di authenticatorAttachment o resident key troppo severi
  • requisiti rigidi di userVerification in segmenti in cui non sono disponibili

Correzione: allenta i vincoli (dove accettabile) o fornisci un percorso alternativo. Per il blocco schermo mancante, considera di rilevare questa condizione e di guidare gli utenti piuttosto che fallire in silenzio (Android).

6.3 DataError#

Significato tipico: gli input sono malformati o incoerenti.

Cause scatenanti comuni:

  • errori di codifica (base64 vs base64url)
  • id di credenziali non valide / formattazione delle challenge

Correzione: convalida e normalizza gli input al confine in cui generi le opzioni WebAuthn. In pratica, DataError è di fatto assente nei sistemi di produzione maturi: se la generazione delle tue opzioni è testata, non la vedrai nelle dashboard.

Se questi errori sono sotto controllo, la domanda successiva riguarda la copertura: gli utenti falliscono perché l'ambiente non può eseguire WebAuthn nel modo in cui ti aspetti?

7. NotSupportedError: lo user agent non supporta le credenziali a chiave pubblica#

NotSupportedError è un segnale di copertura, non un segnale di affidabilità. Di solito significa che un segmento non può eseguire ciò che hai richiesto (sistema operativo/browser troppo vecchio, capacità mancante, funzionalità non abilitata).

Cosa vedrai nella console del browser:

OrigineMessaggio di errore
Chrome, EdgeNotSupportedError: The user agent does not support public key credentials.
FirefoxNotSupportedError: Resident credentials or empty 'allowCredentials' lists are not supported.
Chrome, Edge, FirefoxTypeError: PublicKeyCredential.parseCreationOptionsFromJSON is not a function
Chrome, Edge, FirefoxTypeError: PublicKeyCredential.parseRequestOptionsFromJSON is not a function
Chrome, Edge, FirefoxTypeError: credential.toJSON is not a function
SafariTypeError: Can only call PublicKeyCredential.toJSON on instances of PublicKeyCredential

Le prime due sono vere e proprie NotSupportedError DOMException. Le voci TypeError sono tecnicamente un tipo di eccezione diverso ma rappresentano la stessa classe di problemi: il browser o l'ambiente non supporta ciò che hai richiesto. La famiglia TypeError legata alla serializzazione JSON è molto più comune nella pratica rispetto all'eccezione NotSupportedError vera e propria (vedi sotto).

Le cause comuni includono:

  • browser/versioni del sistema operativo precedenti che non supportano le funzionalità di base di WebAuthn
  • richiesta di funzionalità WebAuthn non disponibili su quella piattaforma
  • tentativo di eseguire flussi specifici della piattaforma su dispositivi non supportati

La famiglia della serializzazione JSON è la più grande fonte di fallimenti della classe NotSupportedError in produzione. Tecnicamente, questi emergono come TypeError (metodo mancante), non come DOMException, ma è qui che li incontrerai. Due cause alla radice distinte:

  1. Il browser non supporta i metodi di serializzazione JSON di WebAuthn. Il browser ha navigator.credentials ma non PublicKeyCredential.parseCreationOptionsFromJSON / parseRequestOptionsFromJSON. Ciò rappresenta circa il 90% di questa famiglia di errori, concentrata nelle versioni meno recenti di Safari e Chrome. Se la tua libreria client dipende da questi metodi senza un fallback, ciò produce un volume di errori significativo.
  2. Le estensioni dei gestori di password interrompono .toJSON(). Le estensioni come Bitwarden, LastPass o 1Password possono intercettare la cerimonia e restituire un oggetto che sembra una credenziale ma non è un'istanza PublicKeyCredential reale. Chiamare .toJSON() su di esso genera un'eccezione, restituisce undefined o l'oggetto è completamente null. Questo rappresenta circa il 10% della famiglia, ma è particolarmente confuso da eseguire il debug perché i messaggi di errore differiscono in base al browser (Safari: "Can only call on instances of PublicKeyCredential"; Firefox: "does not implement interface PublicKeyCredential").

La gestione dovrebbe essere diretta e veloce:

  • ritorna immediatamente alla password/OTP di fallback
  • registra il segmento in modo da poter quantificare i gap di copertura
  • evita di mostrare le CTA delle passkey su segmenti che falliranno costantemente

Se la copertura sembra a posto, ma i fallimenti si verificano ancora in segmenti specifici, potresti avere a che fare con problemi a livello di piattaforma visualizzati come UnknownError.

8. UnknownError: Si è verificato un errore sconosciuto durante la comunicazione con il gestore delle credenziali#

UnknownError è un errore generico per i guasti dell'autenticatore/del sistema operativo che non si mappano in modo pulito nelle altre categorie. È spesso temporaneo, ma può anche verificarsi con dei picchi dopo gli aggiornamenti del sistema operativo.

Cosa vedrai nella console del browser:

OrigineMessaggio di errore
Chrome (Android)UnknownError: An unknown error occurred while talking to the credential manager.
Qualsiasi browserUnknownError: The operation failed for an unknown transient reason.
Qualsiasi browserUnknownError: Either the device has received unexpected request data, or the device has been reconfigured since the request was made.
Qualsiasi browserUnknownError: Something went wrong.
Chrome (LastPass)TypeError: Cannot use 'in' operator to search for 'type' in null
Safari (LastPass)TypeError: null is not an Object. (evaluating 'key in input')
Chrome (Bitwarden)FallbackRequested

Gestione pratica:

  • usa un'UX che supporti i nuovi tentativi (non dare la colpa all'utente)
  • acquisisci i numeri di build del sistema operativo e il contesto del credential-manager/provider ove possibile
  • osserva i picchi specifici del segmento dopo gli aggiornamenti del sistema operativo

Una fonte di nicchia di errori che non si adatta bene a nessuna categoria DOMException: estensioni del browser del gestore di password (come Bitwarden, LastPass, 1Password e altri) possono intercettare le chiamate all'API WebAuthn e restituire risposte non standard. Sebbene di volume ridotto rispetto agli annullamenti degli utenti, vale la pena monitorarli perché influenzano sistematicamente segmenti di utenti specifici e i sintomi sono confusi: metodi mancanti sull'oggetto credenziale restituito, tipi di errore imprevisti o risposte malformate che non corrispondono a nessun errore WebAuthn documentato. Questi emergono spesso come UnknownError o come eccezioni non classificate. Se vedi picchi di errori concentrati in browser specifici senza alcuna spiegazione a livello di sistema operativo, controlla se è coinvolta un'estensione per la gestione delle credenziali.

Finora abbiamo coperto i nomi degli errori dei browser web. Ma se rilasci anche app native, il panorama degli errori è diverso e, per certi versi, nettamente migliore.

9. Una parola sulle app native (iOS e Android)#

Tutto quanto sopra riguarda i browser web. Le app native - iOS con il framework ASAuthorization, Android con Credential Manager - condividono le stesse categorie fondamentali di errori ma differiscono in modo importante:

  1. "Nessuna credenziale" è un segnale distinto. Sul web, i browser raggruppano "nessuna credenziale disponibile" e "utente annullato" nello stesso NotAllowedError per motivi di privacy. Sulle versioni native, utilizzare preferImmediatelyAvailableCredentials su iOS (ASAuthorizationController) o setPreferImmediatelyAvailableCredentials(true) su Android (GetCredentialRequest) indica al sistema operativo di presentare solo le credenziali già presenti sul dispositivo e di fallire immediatamente se non ne esistono. Ciò fornisce un segnale pulito di "nessuna credenziale" che il web non può fornire.

  2. Lo stato del provider di credenziali è visibile. Sulle piattaforme native, in alcune condizioni, puoi sapere quando nessun provider di credenziali (Google Password Manager, iCloud Keychain, 1Password, ecc.) è installato, configurato o impostato come predefinito e reagire a ciò. Sul web, queste informazioni sono nascoste dietro messaggi NotAllowedError opachi.

  3. I messaggi di errore sono più specifici. Poiché l'utente ha installato l'app - e di conseguenza ha stabilito un rapporto di fiducia con il relying party - il sistema operativo fornisce dettagli diagnostici maggiori. Le considerazioni sulla privacy che costringono i browser web a essere vaghi non si applicano allo stesso modo quando l'app è già sul dispositivo. iOS restituisce messaggi localizzati nella lingua del dispositivo dell'utente. Android restituisce tipi di errore strutturati con catene di cause. Questo rende più semplice il debugging ma significa che la gestione degli errori deve tenere conto della localizzazione e dei formati di errore specifici della piattaforma.

9.1 iOS (Framework ASAuthorization)#

iOS espone gli errori delle passkey tramite il framework ASAuthorization. Tutti gli errori arrivano nel callback del delegato authorizationController(controller:didCompleteWithError:) come oggetti NSError.

Classifica per dominio + codice, non per stringa di messaggio. Il dominio di errore primario è com.apple.AuthenticationServices.AuthorizationError (ASAuthorizationError.errorDomain). Esegui il cast dell'errore con let nsError = error as NSError e confrontalo su .domain e .code. Non effettuare mai il match su .localizedDescription in produzione - I messaggi Apple sono localizzati in più di 30 lingue e possono cambiare a seconda delle versioni del sistema operativo. Le stringhe di messaggio elencate di seguito sono utili per riconoscere gli errori nei log, ma non sono criteri di classificazione.

Codici ASAuthorizationError pubblici:

CodiceNomeDaCosa significa
1000UnknowniOS 13Non dovrebbe apparire in produzione. Catch-all generico.
1001CancelediOS 13L'utente ha chiuso il foglio delle passkey. L'errore più comune in assoluto - l'equivalente di NotAllowedError. Segnale pulito con userInfo vuoto e nessun errore di fondo.
1002InvalidResponseiOS 13Corruzione a livello di framework. Raro in pratica.
1003NotHandlediOS 13Nessun provider ha gestito la richiesta. Controlla gli entitlement e la configurazione del provider di credenziali.
1004FailediOS 13Fallimento generico. Il localizedDescription contiene il motivo reale (ad es. "Application with identifier X is not associated with domain Y"). userInfo può contenere una stringa FailureReason, ma NSUnderlyingErrorKey non è sempre popolato: i guasti di associazione al dominio restituiscono nil per l'errore di fondo.
1005NotInteractiveiOS 15Nessuna credenziale disponibile quando si utilizza preferImmediatelyAvailableCredentials. Questo è il segnale "not found" pulito - l'equivalente iOS di "nessuna passkey esiste su questo dispositivo". Non è stata mostrata alcuna interfaccia utente.
1006MatchedExcludedCredentialiOS 18Esiste già una passkey per questo RP su questo dispositivo. Segnale pulito per il rilevamento di duplicati - userInfo vuoto, nessun NSUnderlyingErrorKey. La classificazione funziona senza il matching delle stringhe.
1007CredentialImportiOS 18.2Importazione credenziali non riuscita.
1008CredentialExportiOS 18.2Esportazione credenziali non riuscita.
1009PreferSignInWithAppleiOS 26L'utente preferisce Accedi con Apple alla passkey. Nuovo in iOS 26.
1010DeviceNotConfiguredForPasskeyCreationiOS 26Il dispositivo è privo di passcode o configurazione di iCloud Keychain. Bug noto del simulatore iOS 26: restituisce 1010 anche quando la configurazione è corretta (non si riproduce sui dispositivi fisici).

La distinzione più importante per la produzione: da iOS 18, le credenziali duplicate restituiscono il proprio codice di errore 1006 (MatchedExcludedCredential). Su iOS 17 e versioni precedenti, le credenziali duplicate erano nascoste all'interno del codice 1004 (Failed). Su iOS 18+, la distinzione è strutturale (codice di errore diverso), non testuale.

Errori di runtime comuni (riferimento a livello di log):

Questi messaggi compaiono in localizedDescription o in userInfo per specifici scenari di errore. Utilizzali per le ricerche nei log e il debugging, non per la classificazione a livello di codice.

Messaggio (impostazioni locali inglese)Codice di baseNote
Application with identifier <TeamID.BundleID> is not associated with domain X1004 (Failed)L'entitlement Associated Domains dell'app non corrisponde al relying party. Correggi il file apple-app-site-association sul tuo server.
Couldn't communicate with a helper application.1004 (Failed)L'estensione del provider di credenziali non ha risposto. Temporaneo: è opportuno riprovare.
Request already in progress for specified application identifier.1004 (Failed)Una richiesta ASAuthorization duplicata è stata avviata mentre ne era in sospeso un'altra. Race condition nell'app.
Stolen Device Protection is enabled and biometry is required.1004 (Failed)iOS 17+ Stolen Device Protection blocca l'autenticazione biometrica in luoghi non familiari. Non risolvibile dagli sviluppatori, ma vale la pena informare l'utente.
(AuthenticationServicesCore.ASCABLEClient.ClientError error 2.)Dominio separatoL'handshake Bluetooth dell'autenticazione cross-device (hybrid/CABLE) è fallito.
(AuthenticationServicesCore.ASCABLEClient.ClientError error 3.)Dominio separatoLa connessione Bluetooth dell'autenticazione cross-device è fallita.

Messaggi localizzati "nessuna credenziale" (codice 1005):

Quando preferImmediatelyAvailableCredentials è impostato e non esiste alcuna passkey, iOS restituisce il codice 1005 (NotInteractive) con un messaggio localizzato nella lingua del dispositivo dell'utente. Ciò è esclusivo delle app native: i browser web non espongono mai questo segnale. Il messaggio inizia sempre con The operation couldn't be completed. seguito dal testo localizzato:

LinguaMessaggio
Cinese (Semplificato)没有可用于登录的凭证。
VietnamitaKhông có sẵn thông tin để đăng nhập.
Araboلا تتوفر بيانات اعتماد لتسجيل الدخول.
SpagnoloNo hay ninguna credencial disponible para iniciar sesión.
Cinese (Tradizionale)沒有可用於登入的憑證。
Coreano로그인을 위한 자격 증명이 없습니다.
Francese (Canada)Aucun identifiant disponible pour la connexion.
Portoghese (Brasile)Nenhuma credencial disponível para login.
Francese (Francia)Aucune information d'identification n'est disponible pour procéder à la connexion.
Tailandeseไม่มีข้อมูลประจำตัวสำหรับเข้าสู่ระบบ
ItalianoNon ci sono credenziali disponibili per l'accesso.
OlandeseGeen inloggegevens beschikbaar.
Giapponeseログイン用の資格情報がありません。
TurcoOturum açmak için kullanılabilecek kimlik bilgisi yok.

I dispositivi in ​​lingua inglese in genere risolvono l'errore "nessuna credenziale" a livello di API prima che il framework ASAuthorization restituisca un errore localizzato, motivo per cui non appare alcuna variante inglese qui sopra. A livello di codice, fai sempre affidamento sul codice 1005 anziché analizzare queste stringhe.

9.2 Android (Credential Manager API)#

Android mostra gli errori delle passkey tramite l'API Credential Manager (androidx.credentials). I messaggi di errore includono un messaggio principale e spesso un cause con ulteriori dettagli. Rispetto a iOS, Android fornisce tipi di errore più strutturati e cause più esplicite per i problemi di configurazione.

Annullamento dell'utente e rilevamento delle credenziali:

ErroreNote
User cancelled the operationL'utente ha chiuso il prompt passkey. L'equivalente di NotAllowedError. Nota: il Credential Manager restituisce anche User canceled the request (ortografia USA) da un percorso di codice diverso - entrambi sono identici.
Excluded credential matches existing credentialEsiste già una passkey per questo ID credenziale. L'equivalente di InvalidStateError. A differenza di iOS, il messaggio è distinto dall'annullamento dell'utente.
No create options available.Nessun provider di credenziali idoneo può gestire la richiesta di creazione. In genere significa che i Google Play Services sono obsoleti o che nessun provider di credenziali supporta la creazione di passkey.

Errori di configurazione e sicurezza:

ErroreNote
Passkeys not supported for this appI Digital Asset Links (assetlinks.json) mancano o non contengono l'impronta digitale del certificato di firma dell'app. L'equivalente di SecurityError.
Https failed: respCode=301, url=https://<domain>/.well-known/assetlinks.jsonIl file assetlinks.json restituisce un reindirizzamento invece di un HTTP 200. Android richiede il file all'URL esatto senza reindirizzamenti.
The incoming request cannot be validatedIl Credential Manager non può verificare la richiesta tramite Digital Asset Links.
RP ID cannot be validated.Il relying party ID nelle opzioni WebAuthn non corrisponde a assetlinks.json.
Screen lock is missing.Nessun PIN, sequenza o dato biometrico configurato sul dispositivo. Le passkey richiedono la verifica dell'utente. L'equivalente di ConstraintError.
Cannot find an eligible account.Nessun account Google sul dispositivo è idoneo per la creazione della passkey (raro, in genere configurazioni aziendali personalizzate).

Errori della piattaforma e dell'autenticatore:

ErroreNote
Unsuccessful result from folsom activity.Fallimento interno ai Google Play Services. "Folsom" è un componente GMS per le operazioni passkey. Temporaneo: è opportuno riprovare.
Can't find the proper key to decrypt the private key from WebauthnCredentialSpecifics.Esiste una passkey sincronizzata ma il dispositivo non può decrittografare la sua chiave privata. Lo stato di sincronizzazione del Google Password Manager è incoerente: la credenziale è stata sincronizzata da un altro dispositivo ma la chiave di decrittografia non è disponibile. Non risolvibile dagli sviluppatori.
Operation was interrupted (cause: The UI was interrupted - please try again.)L'interfaccia utente del Credential Manager è stata interrotta da un'altra attività (chiamata in arrivo, rotazione dello schermo, app in background). L'equivalente di AbortError.
Unknown credential errorUn errore catch-all generico quando non si applica alcun tipo di errore specifico. Solitamente transitorio.
timeout (cause: Canceled)L'operazione del Credential Manager è andata in timeout prima che l'utente completasse la verifica biometrica.

10. Mettere tutto insieme: la tassonomia degli errori#

Il diagramma seguente mostra come tutti i livelli descritti in precedenza (infrastruttura, ambiente, tipo di operazione, classificazione e rilevamento) si connettono da un'estremità all'altra. È il modello mentale da tenere a mente quando si progetta il tracciamento degli errori.

L'intuizione chiave: un error.name non elaborato ha senso solo quando sai quale livello dell' ambiente lo ha prodotto, quale operazione era in esecuzione e se l'errore era previsto o imprevisto. Le sezioni sottostanti descrivono cosa registrare e come agire di conseguenza.

11. Cosa registrare in modo che gli errori diventino debuggabili#

La maggior parte della classificazione degli errori in questo articolo può essere eseguita solo con i segnali lato client. Un SDK di osservabilità solo frontend acquisisce abbastanza contesto per classificare la stragrande maggioranza degli errori WebAuthn. Questo è anche il modo in cui è architettato l'SDK di osservabilità di Corbado: il livello lato client gestisce l'attribuzione degli errori, le tempistiche, il contesto dell'operazione e il rilevamento della piattaforma. La registrazione lato server aggiunge un secondo livello per i guasti che solo il backend può vedere.

Il requisito chiave: ogni tentativo deve essere rintracciabile da un capo all'altro. Un id di correlazione condiviso (ad esempio auth_flow_id) collega il contesto lato client con l'esito della verifica del server.

11.1 Segnali lato client (SDK frontend)#

SegnalePerché è importante
error.name + motivo normalizzatoErrore raw del browser + la tua classificazione
Tipo di operazioneConditional UI, login modale, creazione manuale, conditional create, auto-append. CDA (Cross-Device Auth) è una complessità a sé stante.
Contesto ambientale completoOS + versione, browser + versione, marca/modello hardware, impostazioni dell'autenticatore (es. GPM abilitato?)
Contesto dell'autenticatore/del managerRotture delle estensioni e del provider
Tempo trascorso prima dell'erroreRifiuto immediato (<1s) vs annullamento dell'utente (1-15s) vs timeout (30s+)
Stato della rete/connettivitàGli errori di rete spesso si manifestano come errori client. Tieni traccia se l'utente era offline e metti in coda i log da inviare al ripristino.
Se è apparsa la UI QR/ibridaFallimento locale vs cross-device
Id di correlazione (auth_flow_id)Collega con i log del server

11.2 Segnali lato server (Verifica del backend)#

I fallimenti della verifica lato server si verificano dopo che il browser ha restituito una credenziale e una challenge firmata. Questi dovrebbero essere errori strutturati con codici espliciti, e non mescolati nello stesso bucket dei nomi delle DOMException lato client.

SegnalePerché è importante
Mancata corrispondenza / challenge scadutaProblemi di tempistiche della sessione o di replay
Origine / mancata corrispondenza dell'RP IDBug di configurazione multi-dominio
Firma non valida / credenziale non trovataCredenziale eliminata o corrotta. Caso comune: accesso con Conditional UI con una passkey che l'utente ha già eliminato lato server. Usa la Signal API per mantenere sincronizzati gli elenchi di credenziali client e server.
Mancata corrispondenza dell'handle utenteProblemi di mappatura dell'account
Id di correlazione (auth_flow_id)Collega con il contesto lato client

Se desideri un modello a imbuto completo (drop-off in base allo step e conversione tra gli step), vedi l' analisi della telemetria delle passkey.

Substack Icon

Iscriviti al nostro Substack sulle passkey per le ultime novità.

Iscriviti

Con questi dati in atto, la conclusione diventa semplice: la maggior parte degli "errori" si trasforma in correzioni della UX, correzioni della copertura o correzioni di configurazione. Ma costruire e mantenere questa classificazione da soli è un notevole lavoro continuo.

12. Oltre i nomi degli errori: come Corbado trasforma gli errori raw in segnali azionabili#

La checklist di logging mostrata sopra acquisisce segnali raw. Nella produzione su larga scala, error.name da solo non è sufficiente. Costruire questa classificazione da solo è un lavoro notevole e continuo: i messaggi di errore cambiano a ogni release di browser e sistema operativo, i fornitori di password manager distribuiscono aggiornamenti che alterano il comportamento delle cerimonie e nuove firme di errori appaiono con il lancio di ogni funzionalità.

12.1 Perché error.name da solo non è sufficiente#

Lo stesso NotAllowedError può significare sei cose diverse a seconda di tre dimensioni che i browser non separano per te:

DimensioneCosa ti danno i browserCosa ti serve effettivamenteEsempio
Contesto dell'operazioneNotAllowedErrorÈ stato un conditional UI, login modale, creazione manuale, conditional create o auto-append?Android restituisce lo stesso "unknown error" per un login annullato (previsto) e una creazione fallita (imprevisto)
TempisticheNessun dato sulla durataRifiuto immediato (<1s) vs annullamento utente (1-15s) vs timeout (30s+)200ms = rifiuto ambiente; 5s = l'utente ha visto la finestra e ha annullato; 35s = timeout
Piattaforma + autherror.name genericoOS, browser, versione, gestore credenziali per ogni errore"l'utente ha chiuso la finestra" su Chrome e "autofill non disponibile" su Safari emergono entrambi come NotAllowedError

12.2 Cosa acquisisce l'SDK di osservabilità di Corbado#

Questo è il problema che l'SDK di osservabilità di Corbado è concepito per risolvere. È una leggera integrazione frontend che si sovrappone alla tua implementazione passkey esistente, funziona con qualsiasi server WebAuthn e qualsiasi IDP e classifica automaticamente ogni errore WebAuthn lungo tutte e tre le dimensioni:

CapacitàCosa fa
Attribuzione degli erroriAcquisisce sistema operativo, versione OS, browser, versione browser e autenticatore a ogni tentativo di cerimonia
Modalità operativaCollega ogni errore all'operazione specifica (conditional UI, login modale, creazione manuale, conditional create, auto-append) in modo che lo stesso NotAllowedError si risolva in cause radice differenti
Tempistiche dall'inizio dell'azioneRegistra la durata dall'avvio della cerimonia per distinguere i rifiuti immediati, gli annullamenti degli utenti e i timeout senza dover indovinare
Classificazione intelligenteMappa il contesto completo dell'errore (non solo il nome), normalizzando tra diversi Ambienti (OS, hardware, impostazioni). Dà priorità a gruppi di errore distinti come CDA vs Locale e distingue gli errori Previsti (Annullamento Utente) da quelli Imprevisti (Guasto Sistema).
Frammentazione dei gestori di pwdRileva quando le estensioni di gestione credenziali (Bitwarden, 1Password, LastPass) intercettano le cerimonie e restituiscono risposte non standard, separando i guasti causati dall'estensione da quelli della piattaforma

Questo è il livello Observe: visibilità su ciò che sta accadendo, senza cambiare la tua implementazione.

12.3 Due modi di debuggare: Top-Down e Bottom-Up#

La console di gestione di Corbado supporta due percorsi di indagine:

Top-down (dalla dashboard alla causa radice):

  1. Monitoraggio di due tipi distinti di anomalie:
    • Aumento degli errori previsti (Deriva della baseline): Un ambiente specifico (es. iOS 18.2 su iPhone 15) ha registrato un graduale aumento degli "annullamenti utente"? Spesso questo indica un attrito nell'UX introdotto da un aggiornamento del sistema operativo.
    • Aumento degli errori imprevisti (Picchi): Un errore completamente nuovo o un aumento improvviso nei guasti. Questo indica solitamente un cambiamento che provoca interruzioni (aggiornamento interno dello stack IDP) o una regressione in una nuova versione del browser.
  2. Priorità in base all'impatto:
    • P1: Problemi di login. Se i tassi di successo del login scendono, genera un avviso immediato.
    • P2: Problemi di creazione. Monitora le tendenze, ma evita di svegliare gli ingegneri per picchi di "annullamenti utente" nei flussi di creazione.
  3. Analisi approfondita dell'Ambiente: Usa le dimensioni granulari (Hardware, Impostazioni Auth) per isolare se il problema è globale o specifico per i "dispositivi Samsung con Android 14".
  4. Mitigazione: Se viene rilevato un picco critico, tieni pronto un Kill Switch. Disabilita automaticamente o manualmente le passkey per quello specifico ambiente ed esegui il fallback a OTP/Password per preservare i tassi di login mentre indaghi.

Bottom-up (dai modelli di errore all'impatto):

  1. Inizia dalla visualizzazione della classificazione degli errori. Esamina i pattern degli errori classificati e i loro volumi.
  2. Perfeziona le mappature degli errori man mano che emergono nuovi pattern (ad esempio, una nuova versione del browser rilascia un messaggio di errore diverso).
  3. Gli errori vengono correlati in modo incrociato con le variazioni dei KPI e visualizzati come annotazioni sulle dashboard, quindi un picco in un pattern di errore specifico è automaticamente collegato alla metrica che ha influenzato.

Entrambi i percorsi convergono: il top-down ti dice che qualcosa non va, il bottom-up ti dice perché. L' AI Analytics Assistant connette i due consentendoti di porre domande in linguaggio naturale sia sui dati degli errori che sulle metriche di adozione.

I team che desiderano agire su questi segnali possono passare ad Adopt, che aggiunge la passkey intelligence per limitare automaticamente le cerimonie, ottimizzare i prompt di registrazione e ripristinare gli stati interrotti delle passkey. Per ambienti regolamentati o implementazioni su larga scala, Enterprise aggiunge l' hosting single-tenant, l'integrazione SIEM e la configurazione conforme alla PSD2.

Enterprise Icon

Ottieni un whitepaper gratuito sulle passkey per aziende.

Ottieni gratis

13. Conclusione#

I nomi degli errori WebAuthn non sono un verdetto. Sono dei suggerimenti e diventano utilizzabili solo quando li colleghi al tipo di operazione, alle tempistiche e al contesto della piattaforma.

  • Cosa significano in produzione i nomi di errore WebAuthn più comuni? La maggior parte si mappa a un set ridotto di livelli: flusso di controllo utente (NotAllowedError), ciclo di vita dell'app/concorrenza (AbortError), contesto/configurazione di sicurezza (SecurityError), o bug di opzioni/stato (InvalidStateError, ConstraintError, DataError). La stragrande maggioranza del volume è formata da NotAllowedError, e la maggior parte di questi è un comportamento previsto (l'utente ha chiuso il prompt).
  • Come disambiguare NotAllowedError? Usa le tempistiche (rifiuto immediato vs annullamento utente vs timeout), un indicatore QR/ibrido (mancata corrispondenza della disponibilità), il contesto di attivazione dell'utente (soprattutto su iOS/Safari) e il tipo di operazione (conditional UI vs login modale vs creazione passkey vs conditional create). Non trattare tutti i NotAllowedError come un'unica modalità di fallimento.
  • Perché il tipo di operazione è importante? Lo stesso error.name durante un login con conditional UI è un segnale completamente diverso rispetto a durante un conditional create o una creazione manuale di passkey (l'utente ha ignorato la finestra). La registrazione del tipo di operazione insieme all'errore è ciò che trasforma il generico NotAllowedError in un bucket azionabile.
  • Quale contesto minimo rende debuggabili gli errori? Registra error.name, il tipo di operazione, il tempo trascorso prima dell'errore dall'inizio dell'operazione, il tipo di flusso, se è stata mostrata l'interfaccia utente QR/ibrida, il sistema operativo/browser/dispositivo (comprese le versioni), un id di correlazione (auth_flow_id) e i rifiuti di verifica del server come codici espliciti.

Due regole pratiche che si applicano a tutti i tipi di errore: non mostrare mai agli utenti gli errori raw del browser (fornisci sempre un chiaro percorso di fallback) e separa i tentativi locali da quelli QR/ibridi tra più dispositivi, perché falliscono per motivi diversi e necessitano di correzioni diverse. Su larga scala, mantenere la classificazione degli errori attraverso browser, versioni del sistema operativo e gestori di credenziali è un lavoro continuo. Valuta l'utilizzo di un SDK di osservabilità con una libreria di pattern gestita anziché costruire tutto da zero.

Corbado

Chi siamo

Corbado è la Authentication Intelligence Platform per i team CIAM che gestiscono l'autenticazione consumer su larga scala. Ti aiutiamo a vedere ciò che i log IDP e gli strumenti di analytics generici non mostrano: quali dispositivi, versioni di OS, browser e gestori di credenziali supportano i passkey, perché gli enrollment non si trasformano in login, dove il flusso WebAuthn fallisce e quando un aggiornamento di OS o browser interrompe silenziosamente il login — tutto senza sostituire Okta, Auth0, Ping, Cognito o il tuo IDP interno. Due prodotti: Corbado Observe aggiunge osservabilità per i passkey e qualsiasi altro metodo di login. Corbado Connect introduce passkey gestiti con analytics integrato (insieme al tuo IDP). VicRoads gestisce i passkey per oltre 5M di utenti con Corbado (+80 % di attivazione passkey). Parla con un esperto di Passkey

Domande frequenti#

Come faccio a distinguere tra un utente che annulla un prompt per le passkey e il dispositivo che non possiede una passkey?#

Sul web, i browser raggruppano entrambi i casi in NotAllowedError per motivi di privacy, quindi non puoi distinguerli direttamente. Usa le tempistiche come proxy: un errore sotto a 1 secondo in genere significa un rifiuto da parte dell'ambiente o l'assenza di capacità, mentre un lasso di tempo di 1-15 secondi suggerisce che l'utente ha visto e chiuso la finestra di dialogo. Sulle app native per iOS e Android, l'impostazione di preferImmediatelyAvailableCredentials prima della richiesta fornisce un segnale pulito di "nessuna credenziale" (codice iOS 1005, Android GetCredentialRequest) prima ancora che venga mostrata un'interfaccia utente.

Perché il mio tasso di errori WebAuthn è così alto anche se le passkey sembrano funzionare per la maggior parte degli utenti?#

Nelle implementazioni ottimizzate di passkey su larga scala, oltre il 95% degli errori WebAuthn registrati sono annullamenti previsti dall'utente, non guasti di sistema. Il tracciamento dei conteggi raw di error.name senza separare "l'utente ha chiuso il prompt" dai guasti veri e propri gonfia le metriche degli errori e nasconde delle reali regressioni tra i volumi dei NotAllowedError. Dividi i tuoi conteggi in base al tipo di operazione e tratta i bucket di annullamenti utente separatamente da errori inattesi come SecurityError, ConstraintError e DataError.

Cosa significa il codice 1005 di ASAuthorizationError su iOS e come dovrei usarlo?#

Il codice iOS 1005 (NotInteractive) significa che nessuna passkey era disponibile sul dispositivo quando preferImmediatelyAvailableCredentials è stato impostato su ASAuthorizationController e non è stata mostrata alcuna UI all'utente. Questo è il segnale pulito "nessuna passkey esiste su questo dispositivo" che i browser web non possono fornire a causa dei vincoli di privacy. Classifica sempre sul codice numerico, non su localizedDescription, perché i messaggi Apple sono localizzati in più di 30 lingue e possono cambiare tra le varie versioni del sistema operativo.

Come dovrei gestire il NotAllowedError durante un flusso di conditional create o di aggiunta della passkey ad attivazione automatica?#

Durante il conditional create, NotAllowedError, AbortError e InvalidStateError sono tutti risultati previsti e dovrebbero essere ignorati silenziosamente anziché fatti emergere come errori. NotAllowedError indica che l'autofill non è disponibile o che la pagina ha perso il focus, mentre InvalidStateError significa che una passkey esiste già nel provider. Prima di tentare la chiamata, usa getClientCapabilities() per verificare il supporto al conditionalCreate e controlla lo stato di visibilità del documento per evitare di gonfiare i tuoi conteggi di errore.

Quale contesto dovrei registrare accanto a error.name per rendere effettivamente debuggabili i fallimenti di WebAuthn?#

Acquisisci il tipo di operazione (conditional UI, login modale, creazione manuale, conditional create o auto-append), il tempo trascorso prima dell'errore, la versione del sistema operativo, la versione del browser, il modello hardware, se è apparso l'elemento QR/ibrido nell'interfaccia e un ID di correlazione da collegare ai log del lato server. I fallimenti nella verifica del server come la challenge errata, la firma non valida e la credenziale non trovata dovrebbero essere registrati come codici espliciti strutturati, non raggruppati nello stesso bucket insieme ai nomi DOMException del lato client. Questi segnali, sommati fra loro, consentono la classificazione della stragrande maggioranza degli errori in bucket azionabili, senza dover tirare a indovinare.

Scopri come Corbado si integra con la tua distribuzione di passkey e con lo stack di autenticazione esistente.

Esplora la Console

Condividi questo articolo


LinkedInTwitterFacebook