Get your free and exclusive +45-page Authentication Analytics Whitepaper
Retour à l'aperçu

Guide ultime des erreurs WebAuthn en production (2026)

Découvrez ce que signifient les erreurs WebAuthn courantes comme NotAllowedError en production et comment les classer par type d'opération, délai et plateforme.

Vincent Delitz
Vincent Delitz

Créé: 9 février 2026

Mis à jour: 3 juillet 2026

Guide ultime des erreurs WebAuthn en production (2026)

Cette page a été traduite automatiquement. Consultez la version originale en anglais ici.

1. Introduction#

En production, les erreurs WebAuthn prêtent à confusion car les navigateurs exposent un ensemble restreint de noms de DOMException (comme NotAllowedError) qui peuvent représenter plusieurs causes sous-jacentes. De plus, la grande majorité des « erreurs » - souvent plus de 95 % dans les déploiements optimisés à grande échelle - sont en fait des comportements attendus (l'utilisateur a annulé l'invite de clé d'accès du système d'exploitation).

Debugger Icon

Expérimentez les parcours passkey dans le Passkeys Debugger.

Essayer gratuitement

Important : Pour des raisons de confidentialité, les navigateurs ne font pas la distinction entre l'annulation active par l'utilisateur et l'absence d'une clé d'accès. Cependant, dans certaines situations et avec suffisamment de contexte, à la fois sur le web et sur les plateformes natives, certains de ces cas peuvent être différenciés à l'aide de signaux tels que le délai d'exécution.

Si vous recherchez les définitions canoniques de ces noms, commencez par MDN DOMException. Pour connaître les conditions spécifiques à WebAuthn qui conduisent à ces exceptions (et ce que les navigateurs sont tenus d'appliquer), consultez la spécification Web Authentication du W3C.

Si vous traitez toutes les erreurs comme des « bugs », vous ferez fausse route :

  • vous polluerez vos indicateurs d'erreur avec des annulations normales
  • vous manquerez de véritables régressions cachées dans la masse des NotAllowedError
  • vous proposerez une interface utilisateur qui déconcertera les utilisateurs au lieu de les aider à s'en remettre

Dans cet article, nous répondons aux questions suivantes :

  • Que signifient généralement les noms d'erreur WebAuthn les plus courants dans le trafic réel ?
  • Comment désambiguïser NotAllowedError en groupes exploitables (annulation, expiration ou disponibilité) ?
  • Pourquoi la même erreur a-t-elle des significations différentes selon l'opération (connexion avec interface utilisateur conditionnelle, connexion modale, création de clé d'accès ou création conditionnelle) ?
  • Quel contexte minimal devez-vous capturer pour qu'« un échec » devienne un problème reproductible ?
Points clés
  • NotAllowedError est un signal de surface, pas une cause profonde. Cela peut signifier une annulation, une expiration, l'« absence d'informations d'identification locales » ou l'absence d'activation par l'utilisateur selon le contexte.
  • Le type d'opération modifie la signification. La même NotAllowedError signifie des choses différentes lors d'une connexion avec interface utilisateur conditionnelle, d'une connexion modale, d'une création manuelle de clé d'accès, d'une création conditionnelle et d'ajouts déclenchés automatiquement.
  • Le délai depuis le début de l'opération est le signal le plus sous-estimé : immédiat (<1s), annulation par l'utilisateur (1 à 15 s) et expiration (30 s+) sont des catégories fondamentalement différentes.
  • AbortError est généralement un problème de cycle de vie ou de simultanéité (navigation, nouveau rendu, requêtes multiples en cours).
  • SecurityError correspond presque toujours à une configuration/un contexte et est rare dans les déploiements de production matures.
  • Les « noms d'erreur de navigateur » et les « rejets de vérification de serveur » sont des couches différentes. Suivez les rejets de serveur sous forme de codes explicites, et non d'échecs génériques du client.
  • Les noms bruts d'erreur ne sont pas exploitables seuls. Capturez toujours le type d'opération, le délai et le contexte de la plateforme avec error.name afin de classer les erreurs dans des groupes que vous pouvez réellement corriger.
  • L'« environnement » ne se résume pas au Navigateur + SE. Pour vraiment comprendre les erreurs, vous devez suivre la combinaison complète : version du SE, client (version du navigateur/de l'application), paramètres de l'authentificateur (par exemple, statut iCloud/GPM) et le modèle matériel spécifique.
  • Les échecs de connexion sont P1, les échecs de création sont P2. Bien que les erreurs de création (P2) soient souvent plus nombreuses en raison des abandons d'utilisateurs, les erreurs de connexion (P1) bloquent l'accès et nécessitent une alerte immédiate.

2. Un aide-mémoire pour la production#

Si vous avez seulement besoin d'une cartographie rapide pour débloquer le débogage, commencez par ce tableau. Il est axé sur ce que les équipes voient réellement dans les tableaux de bord et les tickets d'assistance.

error.nameCe que cela signifie généralement en productionCe qu'il faut vérifier pour confirmerPremière action (UX + ingénierie)
NotAllowedErrorL'utilisateur a fermé la feuille, a expiré, ou une non-disponibilité s'est retrouvée dans un seul groupe. C'est le plus grand groupe d'erreurs en production.délai d'erreur, apparition d'une interface QR/hybride, si la cérémonie a commencé à partir d'une action réelle de l'utilisateurTraiter comme attendu : restaurer l'interface utilisateur + afficher la solution de secours
AbortErrorVotre application (ou le navigateur) a annulé la cérémonienavigation/nouveau rendu pendant la cérémonie ; appels WebAuthn simultanés ; AbortController.abort()Appliquer une seule requête en cours ; empêcher les changements d'itinéraire ; gérer l'annulation comme un flux de contrôle normal
SecurityErrorContexte/politique non autorisésstratégie origin + RP ID ; iframe/intégration ; HTTPS ; politique de fonctionnalitéCorriger la configuration RP ID/origin ; valider les politiques d'intégration ; assurer un contexte sécurisé
InvalidStateErrorIncohérence d'état (souvent enregistrement en double)enregistrement par rapport à la connexion ; excludeCredentials ; informations d'identification existantes sur l'authentificateurTraiter comme « déjà inscrit » ; ajuster le parcours UX ; corriger la génération d'options
ConstraintErrorLes exigences ne peuvent pas être satisfaitesauthenticatorAttachment, userVerification, exigences de clé résidenteAssouplir les contraintes ou fournir un parcours/une solution de secours. Exemple : Le verrouillage de l'écran est manquant sur Android
DataErrorLes entrées sont mal formées/incohérentesencodage base64url ; formats d'identifiant/défi/identifiant d'utilisateurCorriger l'encodage/la sérialisation ; ajouter une validation dans la génération des options
NotSupportedErrorLa plateforme/le navigateur ne prend pas en charge votre demandeversion de SE/navigateur ; hypothèses de détection de fonctionnalitésBasculer sur une solution de secours immédiatement ; enregistrer le segment ; éviter d'afficher des CTA de clés d'accès pour les environnements non pris en charge
UnknownErrorÉchec générique de la plateforme/l'authentificateurpics après les mises à jour du SE ; build de l'appareil ; problèmes de fournisseur de gestionnaire d'informations d'identificationUX favorable aux tentatives ; capturer les numéros de build ; examiner les pics par segment

Une chose qu'il est facile d'oublier : le même error.name peut signifier des choses très différentes selon le type d'opération. Gardez à l'esprit le contexte de l'opération en lisant les sections ci-dessous. En pratique, les erreurs de création de clés d'accès (enregistrement) dépassent généralement de loin les erreurs de connexion : le tableau ci-dessus s'applique aux deux, mais c'est là que se situe la majeure partie du volume.

Ensuite, nous approfondirons NotAllowedError car c'est celle que vous verrez le plus et que les équipes interprètent mal le plus souvent.

3. NotAllowedError : L'opération a expiré ou n'a pas été autorisée#

NotAllowedError ressemble souvent à « les clés d'accès ont échoué », mais c'est généralement la plateforme qui vous dit que l'utilisateur n'a pas terminé l'interface utilisateur du système d'exploitation. La clé est de la diviser en groupes sur lesquels vous pouvez agir.

Ce que vous verrez dans la console du navigateur :

SourceMessage d'erreur
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.

Tout ceci se présente comme error.name === "NotAllowedError". Le error.message diffère selon le moteur du navigateur et la cause sous-jacente, mais le résultat est le même : la cérémonie ne s'est pas terminée.

Cela s'applique à la fois à la connexion et à la création de clés d'accès. Lors de la connexion (interface utilisateur conditionnelle, modale avec ou sans liste d'autorisation), NotAllowedError signifie généralement que l'utilisateur n'a pas terminé la cérémonie. Lors de la création d'une clé d'accès, la même erreur apparaît pour des raisons différentes : l'utilisateur a fermé la boîte de dialogue de création (la création conditionnelle n'a pas fonctionné ou la page a perdu le focus lors d'un ajout déclenché automatiquement). Le type d'opération modifie la signification de l'erreur et ce que vous devez faire à ce sujet.

Le délai est souvent un signal sous-estimé. Une erreur survenue moins d'une seconde après un clic est généralement un rejet immédiat (l'environnement ne peut pas le faire, le document n'a pas le focus, capacité manquante). Une erreur au bout de quelques secondes est une annulation par l'utilisateur (il a vu la boîte de dialogue et a décidé de ne pas continuer). Une erreur au bout de 30 secondes ou plus est un délai expiré. Sur les plateformes natives, le délai est particulièrement important : les allers-retours de l'authentificateur, les invites biométriques et les transferts du gestionnaire d'informations d'identification ont tous des durées caractéristiques qui vous aident à distinguer « n'a pas fonctionné » de « l'utilisateur s'est éloigné ». Vous ne pouvez toujours pas distinguer facilement si une clé d'accès existait.

3.1 Désambiguïser avec le contexte#

Vous n'avez pas besoin d'un signal parfait. Vous avez besoin de suffisamment de contexte pour éviter de traiter toutes les NotAllowedError de la même manière. iOS/Safari reçoit une attention spécifique ci-dessous car il a des contraintes uniques (exigences d'activation par l'utilisateur dans les versions antérieures), mais en termes de volume brut d'erreurs, Windows et les navigateurs Chromium génèrent souvent plus de NotAllowedError que toute autre plateforme. Ces signaux vous permettent souvent de résoudre 80 % du problème :

SignalSignification probableQue faire ensuite
Échec immédiat (<1s)Rejet de l'environnement : aucune capacité, le document n'a pas le focus, la surface de création conditionnelle n'est pas disponibleVérifier la détection des fonctionnalités ; s'assurer que le document a le focus ; vérifier que l'opération est prise en charge sur cette plateforme
Annulation rapide (1 à 3 s)Invite surprise / sans contexteModifier le moment de l'invite ; ajouter un temps de recharge après l'annulation
Annulation de la durée de l'utilisateur (3 à 15 s)L'utilisateur a vu la boîte de dialogue et a choisi de ne pas continuerUX attendue ; restaurer l'interface utilisateur + afficher la solution de secours
Expiration (30 s+)La cérémonie a expiré sans action de l'utilisateurClasser comme « n'a pas abouti » ; évaluer si l'invite a été remarquée
L'interface utilisateur QR/hybride apparaît avant l'échecAucune information d'identification locale disponible sur cet appareil. Remarque : pour détecter de manière fiable les décisions relatives aux codes QR avant qu'elles ne se produisent, il faut une couche d'intelligence de clés d'accès qui sait si une information d'identification utilisable existe sur l'appareil actuel.Limiter les propositions de clés d'accès ; rendre l'option « Utiliser le téléphone » explicite ; réduire les QR surprises
Concentré sur iOS/Safari et déclenché sans clic ni appuiActivation utilisateur manquanteCommencer la cérémonie à partir d'un véritable geste de l'utilisateur
Lors d'une création conditionnelle ou d'un ajout déclenché automatiquementLe remplissage automatique n'est pas disponible, les informations d'identification existent déjà, ou la page a perdu le focus. Les erreurs de création conditionnelle peuvent apparaître soudainement et en grand nombre lorsque la fonctionnalité est lancée, ce qui en fait l'une des principales sources d'erreur du jour au lendemain.Voir la création conditionnelle ; vérifier l'état de visibilité du document ; utiliser getClientCapabilities() pour vérifier la prise en charge de conditionalCreate avant de tenter l'appel

C'est aussi la raison pour laquelle NotAllowedError devrait rarement être visible par l'utilisateur. Ce n'est pas un message sur lequel l'utilisateur peut agir.

La classification par contexte est également l'endroit où les taux de réussite se divisent le plus nettement. L' analyse du taux de réussite de l'authentification par clé d'accès Corbado Passkey Benchmark 2026 mesure un achèvement au premier trimestre 2026 de 55 à 95 % pour les flux axés sur l'identifiant sur des appareils inconnus par rapport à 95 à 99 % pour les retours sur des appareils connus sur l'ensemble des déploiements B2C à grande échelle. Sur le web iOS, l'approche par l'identifiant atteint 85 à 95 % d'achèvement (% CDA 0 à 5 %), sur le web Android 70 à 85 % (% CDA 5 à 10 %) et sur le web macOS 70 à 85 % (% CDA 10 à 15 %), tandis que le web Windows se situe entre 45 et 60 % d'achèvement de l'approche par l'identifiant avec un % CDA de 55 à 65 % sur Windows 11 et de 40 à 55 % sur Windows 10. Lire le volume de NotAllowedError sans séparer les contextes d'appareils connus et inconnus confond deux régimes de succès fondamentalement différents.

Une nuance qui a de l'importance en production : certains agents utilisateurs peuvent afficher les délais d'expiration sous forme de TimeoutError, mais de nombreuses équipes voient encore les délais s'effondrer dans NotAllowedError dans les tableaux de bord. Quoi qu'il en soit, traitez les expirations comme « la cérémonie ne s'est pas terminée » et classez-les en fonction du délai et du contexte.

3.2 Gestion de l'UX : faire de l'annulation une sortie normale#

Lorsque la feuille du SE est fermée ou expire, votre interface utilisateur doit récupérer immédiatement et réagir avec grâce. Un ensemble de règles pratiques :

  • restaurer l'interface utilisateur de connexion (pas de spinners qui continuent de tourner)
  • conserver l'état de l'identifiant (ne pas forcer une nouvelle saisie)
  • afficher une solution de secours visible sur le même écran
  • éviter les bannières effrayantes pour des résultats attendus

Au-delà des bases :

  • Traitez la première annulation comme normale et proposez une nouvelle tentative avec une explication calme. Ce n'est qu'après une deuxième annulation que vous devez suggérer des options de secours (voir solution de secours et récupération des clés d'accès).
  • Autorisez jusqu'à trois invites de création avant un délai de récupération afin que les utilisateurs surpris aient une deuxième chance (voir les bonnes pratiques de création de clés d'accès).
  • Divisez le nombre d'erreurs entre la création et les connexions afin de comparer ce qui est comparable.
  • Segmentez les taux d'erreur par SE, navigateur et appareil afin de repérer où réside réellement la friction (voir les bonnes pratiques de connexion par clé d'accès).

Si vos « annulations » sont véritablement élevées, la prochaine étape consiste à corriger les causes profondes qui les sous-tendent : chronométrage des invites, surprises liées au code QR et faible disponibilité.

3.3 Corrections techniques qui réduisent les NotAllowedError#

Commencez par les changements qui font évoluer rapidement les indicateurs :

  • Corriger le moment de l'invite et l'activation par l'utilisateur (en particulier sur iOS/Safari) : événements Safari WebAuthn activés par l'utilisateur.
  • Réduire les surprises liées au QR/hybride : pourquoi les flux de clés d'accès affichent des codes QR et pourquoi les utilisateurs abandonnent.
  • Limitez les propositions pour que les clés d'accès soient affichées lorsqu'elles ont de bonnes chances de réussir : ne proposez des clés d'accès que lorsqu'elles sont susceptibles de réussir.
  • Utilisez des modèles qui évitent d'afficher une invite lorsqu'aucune information d'identification locale n'existe : Médiation immédiate WebAuthn.
  • Gérer l'instabilité du réseau : Les erreurs réseau pendant la vérification se manifestent souvent sous la forme d'échecs génériques côté client. Mettez en place une file d'attente hors ligne pour vos journaux de télémétrie afin de ne pas perdre les données d'erreur lorsque la connexion de l'utilisateur est interrompue pendant la cérémonie.
  • Contrôler les cérémonies avec les API de détection afin que les défaillances de l'environnement ne gonflent pas votre groupe NotAllowedError. Commencez par isUVPAA() comme porte la plus basique, puis utilisez getClientCapabilities() pour des vérifications plus fines (création conditionnelle, obtention conditionnelle, transport hybride, authentificateur de plateforme). Soyez conscient que les API de détection peuvent se casser avec les mises à jour du SE : iOS 26.2 a livré un bug WebKit où isUVPAA() renvoie false sur tous les navigateurs basés sur WKWebView même si les clés d'accès fonctionnent parfaitement, provoquant des pics soudains de NotAllowedError pour 10 à 25 % des utilisateurs iOS (voir comment corriger la détection de clé d'accès avec getClientCapabilities()).

3.4 Remarque sur l'évolution des noms d'erreur#

Les noms d'erreur sont une cible mouvante. Il existe des propositions en cours pour ajouter des erreurs WebAuthn plus granulaires (par exemple, pour séparer « aucune information d'identification disponible » de « l'utilisateur a annulé »). En février 2026, cela n'est implémenté dans aucun navigateur, il est donc toujours utile de créer vos propres groupes de causes en fonction du contexte et du délai. Si vous souhaitez suivre ce travail, consultez WebAuthn issue #2062 et l' explication « Nouveaux codes d'erreur ».

Les noms d'erreur restants sont moins fréquents mais méritent tout de même d'être compris lorsqu'ils apparaissent.

4. AbortError : L'opération a été annulée#

AbortError est rare en termes de volume par rapport à NotAllowedError, mais lorsqu'elle apparaît, elle est très révélatrice : elle signifie généralement que la cérémonie ne s'est pas terminée parce que votre application a invalidé la requête (une navigation s'est produite, l'état a changé ou une deuxième requête a démarré).

Ce que vous verrez dans la console du navigateur :

SourceMessage d'erreur
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.

Les causes courantes en production incluent :

  • appels WebAuthn multiples et simultanés (deux invites se font concurrence)
  • changement d'itinéraire / nouveau rendu pendant une cérémonie en cours
  • appel de AbortController.abort() lors des tentatives ou du nettoyage de l'état

Pour y remédier, efforcez-vous de faire de la cérémonie une « section critique » :

  • n'autoriser qu'une seule demande en cours à la fois
  • bloquer la navigation pendant la cérémonie (ou annuler proprement et restaurer l'interface utilisateur)
  • traiter l'annulation comme un flux de contrôle attendu : afficher un bouton de relance et une méthode de secours

Si vous voyez AbortError concentrée dans des surfaces intégrées ou des applications multi-domaines, le groupe suivant à vérifier est SecurityError.

5. SecurityError : WebAuthn n'est pas pris en charge sur les sites avec des erreurs de certificat TLS#

SecurityError est la façon dont le navigateur vous dit : « ce contexte n'est pas autorisé à faire ce que vous avez demandé. » En pratique, il s'agit presque toujours de configuration, et non du comportement de l'utilisateur. Dans les déploiements de production matures, SecurityError est rare car ces problèmes sont généralement détectés lors des tests d'intégration. S'il apparaît en production, cela signifie généralement qu'un nouveau domaine, contexte d'intégration ou cible de déploiement a été ajouté sans la configuration WebAuthn appropriée.

Les causes courantes incluent :

  • Incompatibilité RP ID / origin (configurations multi-domaines)
  • restrictions d'intégration d'origines croisées (iframes)
  • contexte non sécurisé (pas en HTTPS) ou autorisations/politiques bloquées
  • .well-known/webauthn ou .well-known/assetlinks.json mal configuré, manquant ou temporairement indisponible. Des problèmes de réseau pendant la fenêtre critique au cours de laquelle le navigateur récupère ces fichiers provoqueront des échecs. Un angle mort fréquent : si votre page d'accueil est en maintenance, les fichiers well-known sont également hors ligne, ce qui interrompt les cérémonies de clés d'accès sur toutes les parties de confiance qui en dépendent.

Ce que vous verrez dans la console du navigateur :

SourceMessage d'erreur
Chrome, EdgeSecurityError: WebAuthn is not supported on sites with TLS certificate errors.
N'importe quel navigateurSecurityError: 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.

En production, SecurityError est rare : ces erreurs sont presque toujours détectées lors des tests d'intégration. Lorsqu'elles apparaissent, l'erreur de certificat TLS est la plus courante.

La boucle de débogage la plus rapide est la suivante :

  • consignez l'origine et les entrées RP ID que vous avez utilisées
  • reproduisez dans le même contexte (niveau supérieur vs iframe, domaine de prod vs staging)
  • si vous intégrez la connexion, confirmez que la politique d'autorisations est configurée (par exemple publickey-credentials-create / publickey-credentials-get) : MDN Permissions-Policy
  • vérifiez votre stratégie de domaine (voir origines liées)
  • si vous utilisez des iframes, validez les politiques de fonctionnalités (voir clés d'accès dans iframe)

Une fois que SecurityError est gérée, le groupe suivant à traiter sérieusement est l'ensemble des erreurs qui indiquent souvent des bugs d'implémentation : InvalidStateError, ConstraintError et DataError.

PasskeysCheatsheet Icon

Aide-mémoire Passkeys. Conseils pratiques, modèles de déploiement et KPIs pour les programmes passkeys.

Obtenir l'aide-mémoire

6. InvalidStateError, ConstraintError, DataError : traitez-les comme des bugs d'implémentation#

Ces erreurs devraient être rares dans une implémentation mature de clés d'accès. Lorsqu'elles apparaissent, elles indiquent généralement que la génération d'options est incorrecte pour un segment ou que le flux est dans le mauvais état.

6.1 InvalidStateError : « informations d'identification déjà enregistrées auprès de la partie de confiance »#

Ce que vous verrez dans la console du navigateur :

SourceMessage d'erreur
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

Significations typiques :

  • enregistrement : vous avez tenté de créer une information d'identification qui existe déjà (doublon)
  • connexion : moins courant ; signifie souvent que le flux/l'état est incohérent pour la plateforme

Gestion pratique :

  • si cela se produit lors d'un enregistrement manuel, traitez-le comme « déjà inscrit » et redirigez en conséquence
  • assurez-vous que excludeCredentials répertorie tous les ID d'informations d'identification existants pour l'utilisateur afin que l'authentificateur puisse détecter les doublons (voir excludeCredentials)
  • lors d'une création conditionnelle, InvalidStateError est attendue et doit être ignorée silencieusement : cela signifie qu'une clé d'accès existe déjà chez le fournisseur. Il en va de même pour NotAllowedError et AbortError lors d'une création conditionnelle (voir création conditionnelle sur Chrome)

6.2 ConstraintError#

Signification typique : l'authentificateur ne peut pas satisfaire vos contraintes demandées.

Déclencheurs courants :

  • verrouillage de l'écran de l'appareil manquant (en particulier Android) : la plateforme exige une vérification biométrique ou par code PIN, mais l'appareil n'a pas d'écran de verrouillage configuré
  • hypothèses authenticatorAttachment ou clé résidente trop strictes
  • exigences strictes de userVerification dans des segments où elles ne sont pas disponibles

Correction : assouplissez les contraintes (si cela est acceptable) ou fournissez un autre chemin. S'il manque un verrouillage d'écran, envisagez de détecter cette condition et de guider les utilisateurs plutôt que d'échouer silencieusement (Android).

6.3 DataError#

Signification typique : les entrées sont mal formées ou incohérentes.

Déclencheurs courants :

  • erreurs d'encodage (base64 vs base64url)
  • ID d'informations d'identification / formatage de défi invalides

Correction : validez et normalisez les entrées à la limite où vous générez les options WebAuthn. En pratique, DataError est quasiment absente des systèmes de production matures : si la génération de vos options est testée, vous ne verrez pas cela dans les tableaux de bord.

Si ces erreurs sont sous contrôle, la question suivante est la couverture : les utilisateurs échouent-ils parce que l'environnement ne peut pas faire du WebAuthn de la manière que vous attendez ?

7. NotSupportedError : L'agent utilisateur ne prend pas en charge les informations d'identification à clé publique#

NotSupportedError est un signal de couverture, pas un signal de fiabilité. Cela signifie généralement qu'un segment ne peut pas faire ce que vous avez demandé (SE/navigateur trop ancien, capacité manquante, fonctionnalité non activée).

Ce que vous verrez dans la console du navigateur :

SourceMessage d'erreur
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

Les deux premières sont de véritables exceptions DOM NotSupportedError. Les entrées TypeError sont techniquement un type d'exception différent mais représentent la même classe de problème : le navigateur ou l'environnement ne prend pas en charge ce que vous avez demandé. La famille TypeError de sérialisation JSON est bien plus courante en pratique que la DOMException NotSupportedError elle-même (voir ci-dessous).

Les causes courantes incluent :

  • navigateurs/versions de système d'exploitation plus anciens qui ne prennent pas en charge WebAuthn de base
  • demande de fonctionnalités WebAuthn non disponibles sur cette plateforme
  • tentative de flux spécifiques à une plateforme sur des appareils non pris en charge

La famille de sérialisation JSON est la plus grande source d'échecs de la classe NotSupportedError en production. Techniquement, ceux-ci apparaissent comme TypeError (méthode manquante), et non comme une DOMException, mais c'est là que vous les rencontrerez. Deux causes profondes distinctes :

  1. Le navigateur ne prend pas en charge les méthodes de sérialisation JSON WebAuthn. Le navigateur a navigator.credentials mais pas PublicKeyCredential.parseCreationOptionsFromJSON / parseRequestOptionsFromJSON. Cela représente environ 90 % de cette famille d'erreurs, concentrée dans les anciennes versions de Safari et Chrome. Si votre bibliothèque client dépend de ces méthodes sans solution de secours, cela produit un volume d'erreurs important.
  2. Les extensions de gestionnaire de mots de passe cassent .toJSON(). Les extensions telles que Bitwarden, LastPass, ou 1Password peuvent intercepter la cérémonie et renvoyer un objet qui ressemble à une information d'identification mais qui n'est pas une véritable instance de PublicKeyCredential. L'appel de .toJSON() sur ce dernier déclenche une erreur, renvoie undefined, ou l'objet est entièrement null. Cela représente environ 10 % de la famille, mais est particulièrement confus à déboguer car les messages d'erreur diffèrent selon le navigateur (Safari : « Can only call on instances of PublicKeyCredential » ; Firefox : « does not implement interface PublicKeyCredential »).

Le traitement doit être direct et rapide :

  • basculer immédiatement sur un mot de passe/OTP de secours
  • enregistrer le segment afin de pouvoir quantifier les lacunes de couverture
  • éviter d'afficher des CTA de clés d'accès sur les segments qui échoueront systématiquement

Si la couverture semble correcte mais que des échecs se produisent toujours dans des segments spécifiques, vous avez peut-être affaire à des problèmes de couche de plateforme signalés sous la forme d'UnknownError.

8. UnknownError : Une erreur inconnue s'est produite lors de la communication avec le gestionnaire d'informations d'identification#

UnknownError est un fourre-tout pour les pannes d'authentificateur/de système d'exploitation qui ne correspondent pas clairement aux autres catégories. C'est souvent temporaire, mais cela peut également s'accentuer après les mises à jour du système d'exploitation.

Ce que vous verrez dans la console du navigateur :

SourceMessage d'erreur
Chrome (Android)UnknownError: An unknown error occurred while talking to the credential manager.
N'importe quel navigateurUnknownError: The operation failed for an unknown transient reason.
N'importe quel navigateurUnknownError: Either the device has received unexpected request data, or the device has been reconfigured since the request was made.
N'importe quel navigateurUnknownError: 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

Gestion pratique :

  • utiliser une UX favorable aux nouvelles tentatives (ne pas « blâmer l'utilisateur »)
  • capturer les numéros de système d'exploitation/de build et le contexte du gestionnaire/fournisseur d'informations d'identification dans la mesure du possible
  • surveiller les pics spécifiques à un segment après les mises à jour du système d'exploitation

Une source de niche d'erreurs qui ne rentre pas parfaitement dans une catégorie DOMException : les extensions de navigateur de gestionnaire de mots de passe (comme Bitwarden, LastPass, 1Password, et d'autres) peuvent intercepter les appels API WebAuthn et renvoyer des réponses non standard. Bien qu'elles soient faibles en volume par rapport aux annulations d'utilisateurs, elles valent la peine d'être suivies car elles affectent systématiquement des segments d'utilisateurs spécifiques et les symptômes prêtent à confusion : méthodes manquantes sur l'objet d'information d'identification renvoyé, types d'erreurs inattendus ou réponses mal formées qui ne correspondent à aucune erreur WebAuthn documentée. Ceux-ci apparaissent souvent sous la forme de UnknownError ou d'exceptions non classées. Si vous constatez des pics d'erreurs concentrés dans des navigateurs spécifiques sans explication au niveau du système d'exploitation, vérifiez si une extension de gestionnaire d'informations d'identification est impliquée.

Jusqu'à présent, nous avons couvert les noms d'erreur des navigateurs web. Mais si vous créez également des applications natives, le paysage des erreurs est différent - et à certains égards, nettement meilleur.

9. Un mot sur les applications natives (iOS et Android)#

Tout ce qui précède couvre les navigateurs web. Les applications natives - iOS avec le framework ASAuthorization, Android avec Credential Manager - partagent les mêmes catégories d'erreurs fondamentales, mais diffèrent sur des points importants :

  1. « Aucune information d'identification » est un signal distinct. Sur le web, les navigateurs regroupent « aucune information d'identification disponible » et « l'utilisateur a annulé » dans la même NotAllowedError pour des raisons de confidentialité. Sur les applications natives, l'utilisation de preferImmediatelyAvailableCredentials sur iOS (ASAuthorizationController) ou de setPreferImmediatelyAvailableCredentials(true) sur Android (GetCredentialRequest) indique au SE de ne présenter que les informations d'identification déjà présentes sur l'appareil et d'échouer immédiatement s'il n'y en a aucune. Cela vous donne un retour propre « aucune information d'identification » que le web ne peut pas fournir.

  2. Le statut du fournisseur d'informations d'identification est visible. Dans certaines conditions, les plateformes natives peuvent vous dire quand aucun fournisseur d'informations d'identification (Google Password Manager, iCloud Keychain, 1Password, etc.) n'est installé, configuré ou défini par défaut et réagir en conséquence. Sur le web, ces informations sont cachées derrière des messages NotAllowedError opaques.

  3. Les messages d'erreur sont plus spécifiques. Étant donné que l'utilisateur a installé l'application - et a ainsi établi une relation de confiance avec la partie de confiance - le SE affiche plus de détails de diagnostic. Les considérations de confidentialité qui obligent les navigateurs web à être vagues ne s'appliquent pas de la même manière lorsque l'application est déjà sur l'appareil. iOS renvoie des messages localisés dans la langue de l'appareil de l'utilisateur. Android renvoie des types d'erreurs structurés avec des chaînes de cause. Cela rend le débogage plus facile, mais signifie que votre gestion des erreurs doit tenir compte de la localisation et des formats d'erreur spécifiques à la plateforme.

9.1 iOS (Framework ASAuthorization)#

iOS fait remonter les erreurs liées aux clés d'accès via le framework ASAuthorization. Toutes les erreurs arrivent dans le rappel de délégué authorizationController(controller:didCompleteWithError:) en tant qu'objets NSError.

Classez par domaine + code, pas par chaîne de message. Le domaine d'erreur principal est com.apple.AuthenticationServices.AuthorizationError (ASAuthorizationError.errorDomain). Convertissez l'erreur avec let nsError = error as NSError et faites correspondre sur .domain et .code. Ne faites jamais correspondre sur .localizedDescription en production - les messages d'Apple sont traduits dans plus de 30 langues et peuvent changer avec les versions du SE. Les chaînes de messages répertoriées ci-dessous sont utiles pour reconnaître les erreurs dans les journaux, mais ce ne sont pas des critères de classification.

Codes ASAuthorizationError publics :

CodeNomDepuisCe que cela signifie
1000UnknowniOS 13Ne devrait pas apparaître en production. Fourre-tout générique.
1001CancelediOS 13L'utilisateur a fermé la feuille de clés d'accès. Erreur globale la plus courante - l'équivalent de NotAllowedError. Signal clair avec userInfo vide et aucune erreur sous-jacente.
1002InvalidResponseiOS 13Corruption au niveau du framework. Rare en pratique.
1003NotHandlediOS 13Aucun fournisseur n'a traité la demande. Vérifiez les autorisations et la configuration du fournisseur d'informations d'identification.
1004FailediOS 13Échec générique. La localizedDescription contient la raison réelle (par exemple, « Application with identifier X is not associated with domain Y »). userInfo peut contenir une chaîne FailureReason, mais NSUnderlyingErrorKey n'est pas toujours renseigné - les échecs d'association de domaine renvoient nil pour l'erreur sous-jacente.
1005NotInteractiveiOS 15Aucune information d'identification disponible lors de l'utilisation de preferImmediatelyAvailableCredentials. C'est le signal clair « introuvable » - l'équivalent iOS de « aucune clé d'accès n'existe sur cet appareil ». Aucune interface utilisateur n'a été affichée.
1006MatchedExcludedCredentialiOS 18Une clé d'accès existe déjà pour cette partie de confiance sur cet appareil. Signal clair pour la détection des doublons - userInfo vide, pas de NSUnderlyingErrorKey. La classification fonctionne sans correspondance de chaînes.
1007CredentialImportiOS 18.2L'importation d'informations d'identification a échoué.
1008CredentialExportiOS 18.2L'exportation d'informations d'identification a échoué.
1009PreferSignInWithAppleiOS 26L'utilisateur préfère Se connecter avec Apple plutôt que la clé d'accès. Nouveau dans iOS 26.
1010DeviceNotConfiguredForPasskeyCreationiOS 26L'appareil ne dispose pas d'un code d'accès ou d'une configuration iCloud Keychain. Bug connu du simulateur iOS 26 : renvoie 1010 même lorsque la configuration est correcte (ne se reproduit pas sur les appareils physiques).

La distinction la plus importante pour la production : depuis iOS 18, les informations d'identification en double renvoient leur propre code d'erreur 1006 (MatchedExcludedCredential). Sur iOS 17 et versions antérieures, les informations d'identification en double étaient cachées dans le code 1004 (Failed). Sur iOS 18+, la distinction est structurelle (code d'erreur différent), et non textuelle.

Erreurs d'exécution courantes (référence au niveau des journaux) :

Ces messages apparaissent dans localizedDescription ou dans userInfo pour des scénarios de défaillance spécifiques. Utilisez-les pour les recherches de journaux et le débogage, pas pour la classification de manière programmatique.

Message (paramètres régionaux anglais)Code sous-jacentRemarques
Application with identifier <TeamID.BundleID> is not associated with domain X1004 (Failed)Le droit Domaines associés de l'application ne correspond pas à la partie de confiance. Corrigez le fichier apple-app-site-association sur votre serveur.
Couldn't communicate with a helper application.1004 (Failed)L'extension du fournisseur d'informations d'identification n'a pas répondondu. Transitoire - une nouvelle tentative est appropriée.
Request already in progress for specified application identifier.1004 (Failed)Une demande ASAuthorization en double a été déclenchée alors qu'une autre était en cours. Condition de course dans l'application.
Stolen Device Protection is enabled and biometry is required.1004 (Failed)La protection en cas de vol d'appareil sous iOS 17+ bloque l'authentification biométrique dans les endroits peu familiers. Non exploitable par les développeurs, mais mérite d'être signalé à l'utilisateur.
(AuthenticationServicesCore.ASCABLEClient.ClientError error 2.)Domaine séparéL'établissement de liaison Bluetooth d'authentification inter-appareils (hybride/CABLE) a échoué.
(AuthenticationServicesCore.ASCABLEClient.ClientError error 3.)Domaine séparéLa connexion Bluetooth d'authentification inter-appareils a échoué.

Messages localisés « aucune information d'identification » (code 1005) :

Lorsque preferImmediatelyAvailableCredentials est défini et qu'aucune clé d'accès n'existe, iOS renvoie le code 1005 (NotInteractive) avec un message localisé dans la langue de l'appareil de l'utilisateur. C'est unique aux applications natives - les navigateurs web n'exposent jamais ce signal. Le message commence toujours par The operation couldn't be completed. suivi du texte localisé :

LangueMessage
Chinois (simplifié)没有可用于登录的凭证。
VietnamienKhông có sẵn thông tin để đăng nhập.
Arabeلا تتوفر بيانات اعتماد لتسجيل الدخول.
EspagnolNo hay ninguna credencial disponible para iniciar sesión.
Chinois (traditionnel)沒有可用於登入的憑證。
Coréen로그인을 위한 자격 증명이 없습니다.
Français (Canada)Aucun identifiant disponible pour la connexion.
Portugais (Brésil)Nenhuma credencial disponível para login.
Français (France)Aucune information d'identification n'est disponible pour procéder à la connexion.
Thaïไม่มีข้อมูลประจำตัวสำหรับเข้าสู่ระบบ
ItalienNon ci sono credenziali disponibili per l'accesso.
NéerlandaisGeen inloggegevens beschikbaar.
Japonaisログイン用の資格情報がありません。
TurcOturum açmak için kullanılabilecek kimlik bilgisi yok.

Les appareils avec les paramètres régionaux en anglais résolvent généralement le problème « aucune information d'identification » au niveau de l'API avant que le framework ASAuthorization ne renvoie une erreur localisée, c'est pourquoi aucune variante anglaise n'apparaît ci-dessus. Par programmation, faites toujours correspondre le code 1005 plutôt que d'analyser ces chaînes.

9.2 Android (API Credential Manager)#

Android fait remonter les erreurs de clés d'accès via l'API Credential Manager (androidx.credentials). Les messages d'erreur comprennent un message principal et souvent une cause avec des détails supplémentaires. Par rapport à iOS, Android fournit des types d'erreurs plus structurés et des causes plus explicites pour les problèmes de configuration.

Annulation par l'utilisateur et détection des informations d'identification :

ErreurRemarques
User cancelled the operationL'utilisateur a fermé l'invite de clé d'accès. L'équivalent de NotAllowedError. Remarque : le gestionnaire d'informations d'identification renvoie également User canceled the request (orthographe américaine) à partir d'un chemin de code différent - les deux sont identiques.
Excluded credential matches existing credentialUne clé d'accès existe déjà pour cet ID d'informations d'identification. L'équivalent de InvalidStateError. Contrairement à iOS, le message est distinct de l'annulation par l'utilisateur.
No create options available.Aucun fournisseur d'informations d'identification éligible ne peut traiter la demande de création. Cela signifie généralement que les services Google Play sont obsolètes ou qu'aucun fournisseur ne prend en charge la création de clés d'accès.

Erreurs de configuration et de sécurité :

ErreurRemarques
Passkeys not supported for this appLes liens vers des ressources numériques (assetlinks.json) sont manquants ou ne contiennent pas l'empreinte du certificat de signature de l'application. L'équivalent de SecurityError.
Https failed: respCode=301, url=https://<domain>/.well-known/assetlinks.jsonLe fichier assetlinks.json renvoie une redirection au lieu d'un HTTP 200. Android nécessite le fichier à l'URL exacte sans redirection.
The incoming request cannot be validatedLe gestionnaire d'informations d'identification ne peut pas vérifier la demande par rapport aux liens de ressources numériques.
RP ID cannot be validated.L'ID de la partie de confiance dans les options WebAuthn ne correspond pas à assetlinks.json.
Screen lock is missing.Aucun code PIN, schéma ou données biométriques n'est configuré sur l'appareil. Les clés d'accès nécessitent une vérification de l'utilisateur. L'équivalent de ConstraintError.
Cannot find an eligible account.Aucun compte Google sur l'appareil n'est éligible pour la création d'une clé d'accès (rare, généralement dans les configurations d'entreprise personnalisées).

Erreurs de plateforme et d'authentificateur :

ErreurRemarques
Unsuccessful result from folsom activity.Échec interne des services Google Play. « Folsom » est un composant GMS pour les opérations liées aux clés d'accès. Transitoire - une nouvelle tentative est appropriée.
Can't find the proper key to decrypt the private key from WebauthnCredentialSpecifics.Une clé d'accès synchronisée existe, mais l'appareil ne peut pas déchiffrer sa clé privée. L'état de synchronisation de Google Password Manager est incohérent - l'information a été synchronisée depuis un autre appareil, mais la clé de déchiffrement est indisponible. Non exploitable par les développeurs.
Operation was interrupted (cause: The UI was interrupted - please try again.)L'interface du gestionnaire d'informations d'identification a été interrompue par une autre activité (appel entrant, rotation de l'écran, application en arrière-plan). L'équivalent de AbortError.
Unknown credential errorFourre-tout générique lorsqu'aucun type d'erreur spécifique ne s'applique. Généralement temporaire.
timeout (cause: Canceled)L'opération du gestionnaire d'informations d'identification a expiré avant que l'utilisateur n'ait terminé la vérification biométrique.

10. Assembler le tout : la taxonomie des erreurs#

Le diagramme suivant montre comment toutes les couches abordées ci-dessus - infrastructure, environnement, type d'opération, classification et détection - se connectent de bout en bout. C'est le modèle mental que vous devez avoir à l'esprit lors de la conception de votre suivi des erreurs.

L'idée clé : un error.name brut n'a de sens que lorsque vous savez quelle couche de l'environnement l'a produit, quelle opération était en cours d'exécution et si l'erreur était attendue ou inattendue. Les sections ci-dessous expliquent ce qu'il faut consigner et comment agir en conséquence.

11. Ce qu'il faut consigner pour que les erreurs deviennent déboguables#

La majeure partie de la classification des erreurs de cet article peut être effectuée uniquement avec les signaux côté client. Un SDK d'observabilité uniquement frontend capture suffisamment de contexte pour classer la grande majorité des erreurs WebAuthn. C'est également ainsi que le SDK d'observabilité de Corbado est architecturé : la couche côté client gère l'attribution des erreurs, la chronologie, le contexte de l'opération et la détection de la plateforme. La journalisation côté serveur ajoute une deuxième couche pour les échecs que seul le backend peut voir.

L'exigence clé : chaque tentative doit pouvoir être liée de bout en bout. Un identifiant de corrélation partagé (par exemple auth_flow_id) relie le contexte côté client au résultat de la vérification du serveur.

11.1 Signaux côté client (SDK Frontend)#

SignalPourquoi c'est important
error.name + groupe de raisons normaliséErreur brute du navigateur + votre classification
Type d'opérationInterface utilisateur conditionnelle, connexion modale, création manuelle, création conditionnelle, ajout automatique. CDA (Auth inter-appareils) est une véritable complexité.
Contexte environnemental completSE + Version, Navigateur + Version, Marque/Modèle du matériel, Paramètres de l'authentificateur (par exemple, GPM activé ?)
Contexte de l'authentificateur / du gestionnaireBris lié aux extensions et aux fournisseurs
Délai avant l'erreur depuis le début de l'opérationRejet immédiat (<1s) vs annulation de l'utilisateur (1 à 15 s) vs délai d'attente (30 s+)
État du réseau / connectivitéLes erreurs réseau se manifestent souvent sous la forme d'erreurs client. Suivez si l'utilisateur était hors ligne et mettez les journaux en file d'attente pour les envoyer.
Si l'interface QR/hybride est apparueÉchec local par rapport à un échec inter-appareils
Identifiant de corrélation (auth_flow_id)Joindre aux journaux du serveur

11.2 Signaux côté serveur (Vérification par le backend)#

Les échecs de vérification du serveur se produisent une fois que le navigateur a renvoyé des informations d'identification et un défi signé. Celles-ci doivent être des erreurs structurées avec des codes explicites, et non mélangées dans le même groupe que les noms de DOMException côté client. Voir : implémentation du serveur WebAuthn.

SignalPourquoi c'est important
Incohérence du défi / défi expiréProblèmes de timing de session ou de relecture
Incohérence de l'origine / RP IDBugs de configuration multi-domaines
Signature invalide / identifiant introuvableInformations d'identification supprimées ou corrompues. Cas courant : connexion à l'interface utilisateur conditionnelle avec une clé d'accès que l'utilisateur a déjà supprimée côté serveur. Utilisez l'API Signal pour synchroniser les listes d'informations d'identification client et serveur.
Incohérence de l'identifiant de l'utilisateurProblèmes de mappage de compte
Identifiant de corrélation (auth_flow_id)Joindre au contexte côté client

Si vous souhaitez un modèle d'entonnoir complet (abandons par étape et conversion entre les étapes), voir : télémétrie de clé d'accès pour comprendre les abandons.

Substack Icon

Abonnez-vous à notre Substack passkeys pour les dernières actualités.

S'abonner

Avec ces données en place, la conclusion devient simple : la plupart des « erreurs » deviennent soit des corrections d'UX, des corrections de couverture, ou des corrections de configuration. Mais créer et maintenir cette classification vous-même représente un travail continu important.

12. Au-delà des noms d'erreur : comment Corbado transforme les erreurs brutes en signaux exploitables#

La liste de contrôle de journalisation ci-dessus capture les signaux bruts. En production à grande échelle, error.name seul ne suffit pas. Créer cette classification vous-même représente un travail continu important : les messages d'erreur changent avec chaque version de navigateur et de SE, les fournisseurs de gestionnaires de mots de passe déploient des mises à jour qui modifient le comportement de la cérémonie, et de nouvelles signatures d'erreurs apparaissent avec chaque lancement de fonctionnalité.

12.1 Pourquoi error.name seul ne suffit pas#

La même NotAllowedError peut signifier six choses différentes selon trois dimensions que les navigateurs ne séparent pas pour vous :

DimensionCe que les navigateurs vous donnentCe dont vous avez réellement besoinExemple
Contexte de l'opérationNotAllowedErrorS'agissait-il d'une interface utilisateur conditionnelle, d'une connexion modale, d'une création manuelle, d'une création conditionnelle, ou d'un ajout auto ?Android renvoie la même « erreur inconnue » pour une fermeture de connexion (attendue) et un échec de création (inattendu)
DélaiAucune donnée de duréeRejet immédiat (<1s) vs annulation de l'utilisateur (1 à 15 s) vs délai d'attente (30 s+)200 ms = rejet de l'environnement ; 5 s = l'utilisateur a vu la boîte de dialogue et a annulé ; 35 s = délai expiré
Plateforme + authentificateurerror.name génériqueSE, navigateur, version, gestionnaire d'informations d'identification pour chaque erreur« l'utilisateur a fermé la boîte de dialogue » sur Chrome et « remplissage automatique indisponible » sur Safari apparaissent tous deux comme NotAllowedError

12.2 Ce que capture le SDK d'observabilité de Corbado#

C'est le problème que le SDK d'observabilité de Corbado est conçu pour résoudre. Il s'agit d'une intégration frontend légère qui repose sur votre implémentation existante de clés d'accès, fonctionne avec n'importe quel serveur WebAuthn et n'importe quel IDP, et classe chaque erreur WebAuthn selon les trois dimensions automatiquement :

CapacitéCe qu'il fait
Attribution des erreursCapture le SE, la version du SE, le navigateur, la version du navigateur et l'authentificateur à chaque tentative de cérémonie
Mode d'opérationConnecte chaque erreur à l'opération spécifique (interface utilisateur conditionnelle, connexion modale, création manuelle, création conditionnelle, ajout auto) de sorte que la même NotAllowedError se résolve en différentes causes profondes
Temps depuis le début de l'actionEnregistre la durée depuis le début de la cérémonie pour distinguer les rejets immédiats, les annulations des utilisateurs et les expirations sans deviner
Classification intelligente des erreursÉtablit une correspondance sur le contexte d'erreur complet (pas seulement le nom), en normalisant à travers divers Environnements (SE, Matériel, Paramètres). Priorise les groupes d'erreurs distincts comme CDA vs. Local, et distingue les erreurs Attendues (Annulation de l'utilisateur) des erreurs Inattendues (Défaillance système).
Fragmentation du gestionnaire de mots de passeDétecte lorsque les extensions de gestionnaire d'informations d'identification (Bitwarden, 1Password, LastPass) interceptent des cérémonies et renvoient des réponses non standard, séparant les échecs causés par les extensions des échecs de la plateforme

C'est la couche Observer : la visibilité de ce qui se passe, sans modifier votre implémentation.

12.3 Deux façons de déboguer : de haut en bas et de bas en haut#

La console de gestion de Corbado prend en charge deux parcours d'investigation :

De haut en bas (du tableau de bord à la cause profonde) :

  1. Surveiller deux types d'anomalies distinctes :
    • Augmentation des erreurs attendues (dérive de référence) : Est-ce qu'un environnement spécifique (par exemple, iOS 18.2 sur l'iPhone 15) a vu une augmentation progressive des « annulations d'utilisateurs » ? Cela indique souvent une friction d'UX introduite par une mise à jour de l'OS.
    • Augmentation des erreurs inattendues (pics) : Une erreur complètement nouvelle ou une augmentation soudaine des échecs. Cela indique généralement un changement de rupture (mise à jour interne de la pile IDP) ou une régression dans une nouvelle version du navigateur.
  2. Prioriser par impact :
    • P1 : Problèmes de connexion. Si les taux de réussite de connexion chutent, alertez immédiatement.
    • P2 : Problèmes de création. Surveillez les tendances, mais évitez de réveiller les ingénieurs pour des pics d'« annulations d'utilisateurs » dans les flux de création.
  3. Plonger dans l'environnement : Utilisez les dimensions granulaires (matériel, paramètres d'authentification) pour isoler si le problème est global ou spécifique aux « appareils Samsung avec Android 14 ».
  4. Atténuation : Si un pic critique est détecté, préparez un Kill Switch (bouton d'arrêt d'urgence). Désactivez automatiquement ou manuellement les clés d'accès pour cet environnement spécifique et basculez sur les OTP/Mots de passe pour préserver les taux de connexion pendant que vous enquêtez.

De bas en haut (des modèles d'erreurs à l'impact) :

  1. Commencez par la vue de classification des erreurs. Passez en revue les modèles d'erreurs classés et leurs volumes.
  2. Affinez les cartographies d'erreurs à mesure que de nouveaux modèles émergent (par exemple, une nouvelle version de navigateur envoyant un message d'erreur différent).
  3. Les erreurs sont mises en corrélation avec les changements d'indicateurs de performance clés et apparaissent sous forme d'annotations sur les tableaux de bord, de sorte qu'un pic dans un modèle d'erreur spécifique est automatiquement lié à la métrique qu'il a affectée.

Les deux parcours convergent : le haut vers le bas vous indique que quelque chose ne va pas, le bas vers le haut vous dit pourquoi. L' Assistant d'analyse IA relie les deux en vous permettant de poser des questions en langage naturel à la fois sur les données d'erreur et les métriques d'adoption.

Les équipes qui souhaitent agir sur ces signaux peuvent passer à l'Adoption, qui ajoute l'intelligence de clé d'accès pour gérer automatiquement les cérémonies, optimiser les invites d'inscription et réparer les états cassés des clés d'accès. Pour les environnements réglementés ou les déploiements à très grande échelle, la version Enterprise ajoute l'hébergement pour locataire unique, l'intégration SIEM et la configuration conforme à la norme PSD2.

Enterprise Icon

Obtenez un livre blanc gratuit sur les passkeys pour les entreprises.

Obtenir gratuitement

13. Conclusion#

Les noms d'erreur WebAuthn ne constituent pas un verdict. Ce sont des indices - et ils ne deviennent exploitables que lorsque vous les associez au type d'opération, au délai et au contexte de la plateforme.

  • Que signifient les noms d'erreur WebAuthn les plus courants en production ? La plupart renvoient à un petit ensemble de couches : le flux de contrôle de l'utilisateur (NotAllowedError), le cycle de vie de l'application/la concurrence (AbortError), le contexte de sécurité/la configuration (SecurityError), ou des bugs d'options/d'état (InvalidStateError, ConstraintError, DataError). La grande majorité du volume est NotAllowedError, et la plus grande partie correspond à un comportement attendu (l'utilisateur a fermé l'invite).
  • Comment désambiguïser NotAllowedError ? Utilisez le délai (rejet immédiat par rapport à l'annulation de l'utilisateur par rapport à l'expiration), un indicateur QR/hybride (incompatibilité de disponibilité), le contexte d'activation par l'utilisateur (en particulier sur iOS/Safari) et le type d'opération (interface utilisateur conditionnelle par rapport à la connexion modale par rapport à la création de clé d'accès par rapport à la création conditionnelle). Ne traitez pas toutes les NotAllowedError comme un seul mode d'échec.
  • Pourquoi le type d'opération est-il important ? Le même error.name lors d'une connexion avec interface utilisateur conditionnelle est un signal complètement différent que lors d'une création conditionnelle ou d'une création manuelle de clé d'accès (l'utilisateur a fermé la boîte de dialogue). Le fait de consigner le type d'opération avec l'erreur est ce qui transforme une NotAllowedError générique en un groupe exploitable.
  • Quel contexte minimum rend les erreurs déboguables ? Capturez error.name, le type d'opération, le délai avant l'erreur depuis le début de l'opération, le type de flux, si l'interface utilisateur QR/hybride a été affichée, le SE/le navigateur/l'appareil (y compris les versions), un ID de corrélation (auth_flow_id) et les rejets de vérification du serveur sous forme de codes explicites.

Deux règles empiriques qui s'appliquent à tous les types d'erreurs : ne montrez jamais d'erreurs brutes du navigateur aux utilisateurs - fournissez toujours un chemin de secours clair - et séparez les tentatives locales des tentatives inter-appareils QR/hybrides, car elles échouent pour des raisons différentes et nécessitent des corrections différentes. À grande échelle, la maintenance de la classification des erreurs sur tous les navigateurs, les versions de système d'exploitation et les gestionnaires d'informations d'identification est un travail continu. Envisagez d'utiliser un SDK d'observabilité avec une bibliothèque de modèles maintenue plutôt que de la créer de toutes pièces.

Corbado

À propos de Corbado

Corbado est la Authentication Intelligence Platform pour les équipes CIAM qui gèrent l'authentification client à grande échelle. Nous vous montrons ce que les logs IDP et les outils d'analytics génériques ne voient pas : quels appareils, versions d'OS, navigateurs et gestionnaires de credentials prennent en charge les passkeys, pourquoi les enrôlements ne deviennent pas des connexions, où le flux WebAuthn échoue et quand une mise à jour OS ou navigateur casse silencieusement la connexion — le tout sans remplacer Okta, Auth0, Ping, Cognito ni votre IDP interne. Deux produits : Corbado Observe ajoute l'observabilité pour les passkeys et toute autre méthode de connexion. Corbado Connect apporte des passkeys managés avec analytics intégrés (aux côtés de votre IDP). VicRoads gère les passkeys pour plus de 5M d'utilisateurs avec Corbado (+80 % d'activation passkey). Parler à un expert Passkey

Foire aux questions#

Comment faire la différence entre un utilisateur qui annule une invite de clé d'accès et un appareil qui ne possède pas de clé d'accès ?#

Sur le web, les navigateurs regroupent ces deux cas sous NotAllowedError pour des raisons de confidentialité, ce qui empêche de les distinguer directement. Utilisez le délai comme indicateur : une erreur en moins d'une seconde signifie généralement un rejet de l'environnement ou une capacité manquante, tandis que 1 à 15 secondes suggère que l'utilisateur a vu et fermé la boîte de dialogue. Sur les applications natives iOS et Android, la définition de preferImmediatelyAvailableCredentials avant la requête vous donne un signal clair « aucune information d'identification » (code iOS 1005, Android GetCredentialRequest) avant l'affichage de toute interface utilisateur.

Pourquoi mon taux d'erreur WebAuthn est-il si élevé alors que les clés d'accès semblent fonctionner pour la plupart des utilisateurs ?#

Dans les déploiements de clés d'accès optimisés à grande échelle, plus de 95 % des erreurs WebAuthn enregistrées sont des annulations volontaires de l'utilisateur, et non des défaillances du système. Suivre les totaux bruts de error.name sans séparer l'« annulation par l'utilisateur » des véritables défaillances gonfle les statistiques d'erreur et masque de vraies régressions dissimulées dans le volume de NotAllowedError. Divisez vos totaux par type d'opération et traitez les annulations utilisateur séparément des erreurs inattendues telles que SecurityError, ConstraintError et DataError.

Que signifie le code ASAuthorizationError 1005 sur iOS et comment l'utiliser ?#

Le code iOS 1005 (NotInteractive) signifie qu'aucune clé d'accès n'était disponible sur l'appareil lorsque preferImmediatelyAvailableCredentials a été défini sur ASAuthorizationController, et qu'aucune interface utilisateur n'a été affichée. C'est le signal clair indiquant qu'« aucune clé d'accès n'existe sur cet appareil » que les navigateurs web ne peuvent pas fournir en raison des contraintes de confidentialité. Effectuez toujours le classement en fonction du code numérique et non de localizedDescription, car les messages d'Apple sont traduits dans plus de 30 langues et peuvent changer d'une version de système d'exploitation à l'autre.

Comment dois-je gérer NotAllowedError lors d'une création conditionnelle ou d'un flux d'ajout de clé d'accès déclenché automatiquement ?#

Lors de la création conditionnelle, NotAllowedError, AbortError et InvalidStateError sont des résultats attendus et doivent être ignorés silencieusement plutôt que signalés comme des erreurs. NotAllowedError indique que le remplissage automatique n'est pas disponible ou que la page a perdu le focus, tandis que InvalidStateError signifie qu'une clé d'accès existe déjà dans le fournisseur. Avant de tenter l'appel, utilisez getClientCapabilities() pour vérifier la prise en charge de conditionalCreate et l'état de visibilité du document afin d'éviter de gonfler vos comptes d'erreurs.

Quel contexte dois-je consigner avec error.name pour rendre les défaillances WebAuthn réellement déboguables ?#

Capturez le type d'opération (interface utilisateur conditionnelle, connexion modale, création manuelle, création conditionnelle ou ajout automatique), le temps écoulé avant l'erreur depuis le début de l'opération, la version du système d'exploitation, la version du navigateur, le modèle de matériel, l'apparition d'une interface QR/hybride et un ID de corrélation pour faire le lien avec les journaux côté serveur. Les échecs de vérification du serveur (incohérence de défi, signature non valide, informations d'identification introuvables) doivent être consignés en tant que codes structurés explicites, et non mélangés dans le même groupe que les noms de DOMException côté client. Ensemble, ces signaux permettent de classer la grande majorité des erreurs dans des groupes exploitables sans deviner.

Découvrez comment Corbado s’intègre à votre déploiement de passkeys et à votre stack d’authentification existante.

Explorer la Console

Partager cet article


LinkedInTwitterFacebook