Esta página foi traduzida automaticamente. Leia a versão original em inglês aqui.
Em produção, os erros de WebAuthn são confusos porque os navegadores expõem um pequeno conjunto de nomes de DOMException (como NotAllowedError) que podem representar várias causas subjacentes. Além disso, a grande maioria dos "erros" - muitas vezes acima de 95% em implementações otimizadas em grande escala - são, na verdade, comportamento esperado (o usuário cancelou o prompt de chave de acesso do sistema operacional).
Experimente fluxos de passkeys no Passkeys Debugger.
Importante: Por motivos de privacidade, os navegadores não distinguem se o usuário cancelou ativamente ou se não existia uma chave de acesso. No entanto, em algumas situações e com contexto suficiente, tanto na web quanto em plataformas nativas, alguns desses casos podem ser diferenciados usando sinais como o tempo de resposta.
Se você quiser as definições canônicas para esses nomes, comece com a documentação do MDN DOMException. Para condições específicas de WebAuthn que levam a essas exceções (e o que os navegadores são obrigados a aplicar), consulte a especificação W3C Web Authentication.
Se você tratar todos os erros como "bugs", fará as coisas erradas:
NotAllowedErrorNeste artigo, nós respondemos:
NotAllowedError em categorias acionáveis (cancelamento vs tempo limite vs disponibilidade)?Artigos recentes
⚙️
Guia de consulta rápida de chaves de acesso para desenvolvedores
👤
Como excluir uma chave de acesso na Apple, Windows e Android
📖
Guia definitivo sobre erros de WebAuthn em produção (2026)
📖
Explicação técnica da UI condicional do WebAuthn (Preenchimento automático de chaves de acesso)
📖
Chaves de acesso no Brave Browser (2026): O que funciona e o que falha
NotAllowedError é um sinal de superfície, não uma causa raiz. Pode significar cancelamento, tempo limite, "nenhuma credencial local", ou falta de ativação do usuário dependendo do contexto.NotAllowedError significa coisas diferentes durante o login com Conditional UI, login modal, criação manual de chaves de acesso, criação condicional e adições acionadas automaticamente.<1s), cancelamento pelo usuário (1 a 15s) e tempo limite (30s+) são categorias fundamentalmente diferentes.AbortError geralmente é um problema de ciclo de vida/concorrência (navegação, re-renderização, múltiplas requisições em andamento).SecurityError é quase sempre configuração/contexto e raro em implementações maduras em produção.error.name para que você possa classificar os erros em categorias que possa realmente corrigir.Se você precisa apenas de um mapeamento rápido para desbloquear a depuração, comece com esta tabela. Ela é focada no que as equipes realmente veem em painéis e tickets de suporte.
error.name | O que geralmente significa em produção | O que verificar para confirmar | Primeira ação (UX + engenharia) |
|---|---|---|---|
NotAllowedError | Usuário descartou a tela, tempo limite excedido, ou incompatibilidade de disponibilidade agrupados em uma única categoria. Esta é a maior categoria de erro em produção. | tempo até o erro, se a interface QR/híbrida apareceu, se a cerimônia começou a partir de uma ação real do usuário | Tratar como esperado: restaurar UI + mostrar alternativa |
AbortError | Seu aplicativo (ou o navegador) abortou a cerimônia | navegação/re-renderização durante a cerimônia; chamadas WebAuthn concorrentes; AbortController.abort() | Forçar uma solicitação em andamento; evitar mudanças de rota; tratar o aborto como fluxo de controle normal |
SecurityError | Contexto/política não permitida | estratégia de ID de RP + origem; iframe/incorporação; HTTPS; feature policy | Corrigir configuração de origem/ID de RP; validar políticas de incorporação; garantir contexto seguro |
InvalidStateError | Incompatibilidade de estado (frequentemente registro duplicado) | registro vs login; excludeCredentials; credencial existente no autenticador | Tratar como "já inscrito"; ajustar o caminho da UX; corrigir a geração de opções |
ConstraintError | Requisitos não podem ser satisfeitos | authenticatorAttachment, userVerification, requisitos de chaves residentes | Relaxar restrições ou fornecer caminho/alternativa. Exemplo: Bloqueio de tela ausente no Android |
DataError | Entradas malformadas/inconsistentes | codificação base64url; formatos de id/desafio/identificador do usuário | Corrigir codificação/serialização; adicionar validação na geração de opções |
NotSupportedError | Plataforma/navegador não suporta o que você pediu | versão do SO/navegador; suposições de detecção de recursos | Recorrer imediatamente a alternativa; registrar segmento; evitar mostrar CTAs de chaves de acesso para ambientes não suportados |
UnknownError | Plataforma/autenticador falhou de maneira genérica | picos após atualizações do SO; build do dispositivo; problemas no provedor de gerenciamento de credenciais | UX amigável para novas tentativas; capturar números de build; investigar picos de segmentos |
Uma coisa fácil de perder: o mesmo error.name pode significar coisas muito diferentes dependendo do tipo de operação. Tenha em mente o contexto da operação ao ler as seções abaixo. Na prática, os erros de criação de chaves de acesso (registro) normalmente superam os erros de login por uma grande margem - a tabela acima se aplica a ambos, mas a criação é onde reside a maior parte do volume.
A seguir, nos aprofundaremos em NotAllowedError porque é o que você verá com mais frequência e o que as equipes interpretam mal com mais frequência.
O NotAllowedError muitas vezes parece "chaves de acesso falharam", mas geralmente é a plataforma informando que o usuário não concluiu a interface do SO. O segredo é dividi-lo em categorias nas quais você possa agir.
O que você verá no console do navegador:
| Fonte | Mensagem de erro |
|---|---|
| Chrome, Edge | NotAllowedError: The operation either timed out or was not allowed. See: https://www.w3.org/TR/webauthn-2/#sctn-privacy-considerations-client. |
| Safari, WebKit | NotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission. |
| Safari, WebKit | NotAllowedError: This request has been cancelled by the user. |
| Chrome, Edge | NotAllowedError: The operation is not allowed at this time because the page does not have focus. |
| Safari, WebKit | NotAllowedError: The document is not focused. |
| Firefox | NotAllowedError: Operation failed. |
Todos esses aparecem como error.name === "NotAllowedError". O error.message difere de acordo com o mecanismo do navegador e a causa subjacente, mas o resultado é o mesmo: a cerimônia não foi concluída.
Isso se aplica tanto ao login quanto à criação de chaves de acesso. Durante o login (Conditional UI, modal com ou sem lista de permissões), NotAllowedError normalmente significa que o usuário não concluiu a cerimônia. Durante a criação da chave de acesso, o mesmo erro surge por motivos diferentes: o usuário dispensou a caixa de diálogo de criação (a criação condicional não funcionou, ou a página perdeu o foco durante uma adição acionada automaticamente). O tipo de operação altera o que o erro significa e o que você deve fazer a respeito.
O tempo de resposta é frequentemente um sinal subestimado. Um erro com menos de um segundo após um clique geralmente é uma rejeição imediata (o ambiente não pode fazer isso, documento sem foco, recurso ausente). Um erro após alguns segundos é um cancelamento do usuário (ele viu a caixa de diálogo e decidiu não prosseguir). Um erro após 30+ segundos é um tempo limite. Em plataformas nativas, o tempo é especialmente importante: as viagens de ida e volta do autenticador, os prompts biométricos e as transferências do gerenciador de credenciais têm durações características que ajudam a separar "não funcionou" de "o usuário se afastou". Você ainda não pode distinguir facilmente se uma chave de acesso existia.
Você não precisa de um sinal perfeito. Você precisa de contexto suficiente para evitar tratar todos os NotAllowedError da mesma forma. O iOS/Safari recebe atenção específica abaixo porque possui restrições exclusivas (requisitos de ativação do usuário em versões anteriores), mas em volume de erro bruto, o Windows e os navegadores Chromium geralmente geram mais NotAllowedError do que qualquer outra plataforma. Esses sinais geralmente o levam a 80% do caminho:
| Sinal | Significado provável | O que fazer a seguir |
|---|---|---|
Falha imediata (<1s) | Rejeição do ambiente: sem capacidade, documento sem foco, superfície de criação condicional indisponível | Verificar detecção de recursos; garantir que o documento tenha foco; verificar se a operação é suportada nesta plataforma |
| Cancelamento rápido (1 a 3s) | Prompt surpresa / sem contexto | Alterar o tempo do prompt; adicionar período de espera (cooldown) após o cancelamento |
| Cancelamento do usuário (3 a 15s) | O usuário viu a caixa de diálogo e optou por não prosseguir | UX esperada; restaurar a interface + mostrar alternativa |
| Tempo limite (30s+) | A cerimônia atingiu o tempo limite sem ação do usuário | Classificar como "não concluído"; considerar se o prompt foi notado |
| UI QR/híbrida aparece antes da falha | Nenhuma credencial local disponível neste dispositivo. Nota: detectar confiavelmente as decisões do código QR antes que elas aconteçam requer uma camada de inteligência de chaves de acesso que saiba se uma credencial utilizável existe no dispositivo atual. | Restringir as ofertas de chaves de acesso; tornar "Usar telefone" explícito; reduzir códigos QR surpresa |
| Concentrado no iOS/Safari e acionado sem um clique/toque | Ativação do usuário ausente | Iniciar a cerimônia a partir de um gesto real do usuário |
| Durante a criação condicional ou adição automática | Preenchimento automático não disponível, a credencial já existe, ou a página perdeu o foco. Os erros de criação condicional podem aparecer repentinamente e em alto volume quando o recurso é lançado, tornando esta uma das maiores fontes de erro da noite para o dia. | Ver criação condicional; verificar o estado de visibilidade do documento; usar getClientCapabilities() para verificar o suporte a conditionalCreate antes de tentar a chamada |
É também por isso que NotAllowedError raramente deve ser visível para o usuário. Não é uma mensagem sobre a qual o usuário possa agir.
A classificação de contexto também é onde as taxas de sucesso se dividem mais acentuadamente. A análise da taxa de sucesso de autenticação por chaves de acesso do Corbado Passkey Benchmark 2026 mede a conclusão do primeiro trimestre de 2026 em 55-95% para fluxos com identificador primeiro em dispositivos desconhecidos versus 95-99% para retornos de dispositivos conhecidos em implantações B2C de grande escala. O identificador primeiro na web do iOS atinge a conclusão de 85-95% (% CDA 0-5%), na web do Android em 70-85% (% CDA 5-10%) e na web do macOS em 70-85% (% CDA 10-15%), enquanto a web do Windows fica em 45-60% de conclusão de identificador primeiro com % CDA em 55-65% no Windows 11 e 40-55% no Windows 10. Ler o volume de NotAllowedError sem separar contextos de dispositivos conhecidos versus desconhecidos confunde dois regimes de sucesso fundamentalmente diferentes.
Uma nuance que importa em produção: alguns agentes de usuário podem expor tempos limites como TimeoutError, mas muitas equipes ainda veem os tempos limites colapsarem em NotAllowedError nos painéis. De qualquer forma, trate os tempos limites como "cerimônia não concluída" e classifique usando o tempo mais o contexto.
Quando a tela do SO for fechada ou o tempo expirar, sua UI deve se recuperar imediatamente e reagir de forma suave. Um conjunto prático de regras:
Além do básico:
Se os seus "cancelamentos" são genuinamente altos, o próximo passo é corrigir as causas raiz por trás deles: tempo do prompt, surpresas de QR e baixa disponibilidade.
Comece com as mudanças que movem as métricas rapidamente:
NotAllowedError. Comece com isUVPAA() como o portão mais básico e use getClientCapabilities() para verificações mais detalhadas (criação condicional, obtenção condicional, transporte híbrido, autenticador de plataforma). Esteja ciente de que as APIs de detecção podem quebrar com atualizações do SO: o iOS 26.2 lançou um bug no WebKit em que isUVPAA() retorna false em todos os navegadores baseados em WKWebView, embora as chaves de acesso funcionem bem, causando picos repentinos de NotAllowedError para 10 a 25% dos usuários do iOS.Nomes de erros são um alvo móvel. Há propostas em andamento para adicionar erros de WebAuthn mais granulares (por exemplo, para separar "nenhuma credencial disponível" de "usuário cancelado"). Em fevereiro de 2026, isso não estava implementado em nenhum navegador, portanto, ainda vale a pena criar suas próprias categorias de motivo com base no contexto e no tempo. Se você quiser acompanhar esse trabalho, consulte a questão #2062 do WebAuthn e a explicação "New Error Codes".
Os nomes de erro restantes são menos frequentes, mas ainda vale a pena entendê-los quando aparecem.
AbortError é incomum em volume em comparação com NotAllowedError, mas quando aparece é altamente diagnóstico: geralmente significa que a cerimônia não terminou porque seu aplicativo invalidou a solicitação - ocorreu navegação, o estado mudou ou uma segunda solicitação foi iniciada.
O que você verá no console do navegador:
| Fonte | Mensagem de erro |
|---|---|
| Chrome, Edge | AbortError: The operation was aborted. |
| Chrome, Edge | AbortError: Aborted by AbortSignal. |
| Firefox | AbortError: signal is aborted without reason |
| Firefox | AbortError: Operation timed out. |
| Safari, WebKit | AbortError: The user aborted a request. |
| Chrome | AbortError: CredentialContainer request is not allowed. |
Causas de produção comuns incluem:
AbortController.abort() durante repetições ou limpeza de estadoPara corrigir isso, concentre-se em tornar a cerimônia uma "seção crítica":
Se você observar o AbortError concentrado em superfícies embutidas ou aplicativos de vários domínios, o próximo balde a verificar será o SecurityError.
SecurityError é o navegador dizendo a você: "este contexto não tem permissão para fazer o que você pediu". Na prática, quase sempre é uma configuração, não um comportamento do usuário. Em implantações de produção maduras, o SecurityError é raro porque esses problemas geralmente são detectados durante os testes de integração. Se aparecer em produção, geralmente significa que um novo domínio, contexto de incorporação ou destino de implantação foi adicionado sem a configuração correta do WebAuthn.
Causas comuns incluem:
.well-known/webauthn ou .well-known/assetlinks.json mal configurado, ausente ou temporariamente indisponível. Problemas de rede durante a janela crítica em que o navegador busca esses arquivos causarão falhas. Um ponto cego comum: se sua página inicial estiver fora do ar para manutenção, os arquivos well-known também estarão offline, interrompendo as cerimônias de chaves de acesso em todas as partes confiáveis que dependem deles.O que você verá no console do navegador:
| Fonte | Mensagem de erro |
|---|---|
| Chrome, Edge | SecurityError: WebAuthn is not supported on sites with TLS certificate errors. |
| Qualquer navegador | SecurityError: 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. |
Em produção, SecurityError é raro - quase sempre são detectados durante os testes de integração. Quando aparecem, o erro de certificado TLS é o mais comum.
O ciclo de depuração mais rápido é:
publickey-credentials-create / publickey-credentials-get): MDN Permissions-PolicyUma vez tratado o SecurityError, o próximo grupo a ser levado a sério é o conjunto de erros que muitas vezes indicam bugs de implementação: InvalidStateError, ConstraintError e DataError.

Cheatsheet de Passkeys. Guias práticos, padrões de implementação e KPIs para programas de passkeys.
Esses erros devem ser raros em uma implementação de chaves de acesso madura. Quando aparecem, geralmente indicam que a geração da opção está errada para um segmento ou que o fluxo está no estado errado.
O que você verá no console do navegador:
| Fonte | Mensagem de erro |
|---|---|
| Safari, WebKit | InvalidStateError: The user attempted to register an authenticator that contains one of the credentials already registered with the relying party. |
| Chrome, Edge | InvalidStateError: At least one credential matches an entry of the excludeCredentials list in the platform attached authenticator. |
| Chrome, Edge | InvalidStateError: A request is already pending. |
| Firefox | InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable |
Significados típicos:
Tratamento prático:
excludeCredentials liste todos os IDs de credenciais existentes para o usuário, de modo que o autenticador possa detectar duplicatasInvalidStateError é esperado e deve ser ignorado silenciosamente: significa que já existe uma chave de acesso no provedor. O mesmo se aplica a NotAllowedError e AbortError durante a criação condicional (consulte criação condicional no Chrome).Significado típico: o autenticador não pode satisfazer as restrições solicitadas.
Gatilhos comuns:
authenticatorAttachment ou chaves residentesuserVerification muito rígidos em segmentos onde não estão disponíveisCorreção: relaxe as restrições (onde aceitável) ou forneça um caminho alternativo. Em relação à falta de bloqueio de tela, considere detectar essa condição e orientar os usuários em vez de falhar silenciosamente (Android).
Significado típico: as entradas são malformadas ou inconsistentes.
Gatilhos comuns:
Correção: valide e normalize as entradas no limite onde você gera as opções de WebAuthn. Na prática, DataError é efetivamente ausente em sistemas de produção maduros - se a sua geração de opções for testada, você não verá isso nos painéis.
Se esses erros estiverem sob controle, a próxima pergunta é sobre a cobertura: os usuários estão falhando porque o ambiente não pode executar o WebAuthn da maneira que você espera?
NotSupportedError é um sinal de cobertura, não de confiabilidade. Geralmente significa que um segmento não pode fazer o que você pediu (SO/navegador muito antigo, capacidade ausente, recurso não ativado).
O que você verá no console do navegador:
| Fonte | Mensagem de erro |
|---|---|
| Chrome, Edge | NotSupportedError: The user agent does not support public key credentials. |
| Firefox | NotSupportedError: Resident credentials or empty 'allowCredentials' lists are not supported. |
| Chrome, Edge, Firefox | TypeError: PublicKeyCredential.parseCreationOptionsFromJSON is not a function |
| Chrome, Edge, Firefox | TypeError: PublicKeyCredential.parseRequestOptionsFromJSON is not a function |
| Chrome, Edge, Firefox | TypeError: credential.toJSON is not a function |
| Safari | TypeError: Can only call PublicKeyCredential.toJSON on instances of PublicKeyCredential |
Os dois primeiros são NotSupportedError DOMExceptions genuínos. As entradas TypeError são tecnicamente um tipo de exceção diferente, mas representam a mesma classe de problema: o navegador ou ambiente não suporta o que você pediu. A família TypeError de serialização JSON é muito mais comum na prática do que a própria NotSupportedError DOMException (veja abaixo).
Causas comuns incluem:
A família de serialização JSON é a maior fonte de falhas da classe NotSupportedError na produção. Tecnicamente, estas aparecem como TypeError (método ausente), não como um DOMException, mas é onde você as encontrará. Duas causas básicas distintas:
navigator.credentials, mas não tem PublicKeyCredential.parseCreationOptionsFromJSON / parseRequestOptionsFromJSON. Isso representa cerca de 90% dessa família de erros, concentrando-se em versões mais antigas do Safari e do Chrome. Se a sua biblioteca cliente depende desses métodos sem uma alternativa, isso produzirá um volume significativo de erros..toJSON(). Extensões como Bitwarden, LastPass ou 1Password podem interceptar a cerimônia e retornar um objeto que parece uma credencial, mas não é uma instância real de PublicKeyCredential. Chamar .toJSON() nele lança uma exceção, retorna "undefined", ou o objeto é totalmente null. Isso é cerca de 10% da família, mas é especialmente confuso para depurar, pois as mensagens de erro diferem por navegador (Safari: "Can only call on instances of PublicKeyCredential"; Firefox: "does not implement interface PublicKeyCredential").O tratamento deve ser direto e rápido:
Se a cobertura parece adequada, mas as falhas ainda acontecem em segmentos específicos, você pode estar lidando com problemas da camada de plataforma exibidos como UnknownError.
UnknownError é um genérico para falhas do autenticador/SO que não se mapeiam de maneira precisa para as outras categorias. Muitas vezes é transitório, mas também pode ter picos após atualizações do SO.
O que você verá no console do navegador:
| Fonte | Mensagem de erro |
|---|---|
| Chrome (Android) | UnknownError: An unknown error occurred while talking to the credential manager. |
| Qualquer navegador | UnknownError: The operation failed for an unknown transient reason. |
| Qualquer navegador | UnknownError: Either the device has received unexpected request data, or the device has been reconfigured since the request was made. |
| Qualquer navegador | UnknownError: 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 |
Tratamento prático:
Uma fonte de nicho de erros que não se encaixa perfeitamente em nenhuma categoria de DOMException: extensões de navegador de gerenciadores de senha (como Bitwarden, LastPass, 1Password e outros) podem interceptar chamadas da API WebAuthn e retornar respostas não padronizadas. Embora pequenos em volume em comparação com cancelamentos do usuário, vale a pena acompanhá-los porque afetam segmentos de usuários específicos consistentemente e os sintomas são confusos: métodos ausentes no objeto de credencial retornado, tipos de erro inesperados ou respostas malformadas que não correspondem a nenhum erro WebAuthn documentado. Geralmente eles aparecem como UnknownError ou como exceções não classificadas. Se você vir picos de erro concentrados em navegadores específicos sem explicação no nível do SO, verifique se uma extensão do gerenciador de credenciais está envolvida.
Até agora cobrimos nomes de erro em navegadores da web. Mas se você também envia aplicativos nativos, o cenário de erros é diferente - e em alguns aspectos, significativamente melhor.
Tudo acima abrange os navegadores da web. Aplicativos nativos - iOS com o framework ASAuthorization, Android com o Credential Manager - compartilham as mesmas categorias fundamentais de erro, mas diferem de forma importante:
"Nenhuma credencial" é um sinal distinto. Na web, os navegadores combinam "nenhuma credencial disponível" e "usuário cancelou" no mesmo NotAllowedError por privacidade. Em nativo, usar preferImmediatelyAvailableCredentials no iOS (ASAuthorizationController) ou setPreferImmediatelyAvailableCredentials(true) no Android (GetCredentialRequest) diz ao SO para apenas apresentar as credenciais que já estão no dispositivo e falhar imediatamente se não houver nenhuma. Isso fornece um retorno limpo "nenhuma credencial" que a web não pode fornecer.
O status do provedor de credenciais é visível. Plataformas nativas em algumas condições podem informar quando nenhum provedor de credencial (Google Password Manager, iCloud Keychain, 1Password, etc.) está instalado, configurado, ou definido como padrão e reagir a isso. Na web, essas informações estão escondidas atrás de mensagens NotAllowedError opacas.
As mensagens de erro são mais específicas. Porque o usuário instalou o aplicativo - e assim estabeleceu uma relação de confiança com a parte confiável - o SO apresenta detalhes de diagnóstico maiores. As considerações de privacidade que forçam os navegadores da web a serem vagos não se aplicam da mesma forma quando o aplicativo já está no dispositivo. O iOS retorna mensagens localizadas no idioma do dispositivo do usuário. O Android retorna tipos de erro estruturados com cadeias de causas. Isso torna a depuração mais fácil, mas significa que seu tratamento de erros deve levar em consideração a localização e os formatos de erro específicos da plataforma.
O iOS apresenta os erros de chave de acesso através do framework ASAuthorization. Todos os erros chegam no retorno de chamada do delegado authorizationController(controller:didCompleteWithError:) como objetos NSError.
Classifique por domínio + código, não pela string de mensagem. O domínio de erro principal é com.apple.AuthenticationServices.AuthorizationError (ASAuthorizationError.errorDomain). Faça a conversão do erro com let nsError = error as NSError e combine em .domain e .code. Nunca compare com .localizedDescription em produção - as mensagens da Apple estão localizadas em 30+ idiomas e podem mudar de acordo com a versão do SO. As strings de mensagem listadas abaixo são úteis para reconhecer erros em logs, mas não são critérios de classificação.
Códigos públicos do ASAuthorizationError:
| Código | Nome | Desde | O que significa |
|---|---|---|---|
| 1000 | Unknown | iOS 13 | Não deve aparecer em produção. Captura geral. |
| 1001 | Canceled | iOS 13 | Usuário fechou a tela de chave de acesso. O erro mais comum em geral - o equivalente a NotAllowedError. Sinal limpo com userInfo vazio e sem erro subjacente. |
| 1002 | InvalidResponse | iOS 13 | Corrupção ao nível do framework. Raro na prática. |
| 1003 | NotHandled | iOS 13 | Nenhum provedor atendeu a solicitação. Verifique direitos e configurações do provedor de credenciais. |
| 1004 | Failed | iOS 13 | Falha genérica. O localizedDescription contém a verdadeira razão (ex. "Aplicativo com identificador X não está associado ao domínio Y"). O userInfo pode conter uma string FailureReason, mas NSUnderlyingErrorKey não está sempre preenchido - falhas de associação de domínio retornam nulo para o erro subjacente. |
| 1005 | NotInteractive | iOS 15 | Nenhuma credencial disponível ao usar preferImmediatelyAvailableCredentials. Este é o sinal claro de "não encontrado" - o equivalente do iOS a "nenhuma chave de acesso existe neste dispositivo". Nenhuma UI foi exibida. |
| 1006 | MatchedExcludedCredential | iOS 18 | Já existe uma chave de acesso para este RP neste dispositivo. Sinal claro para detecção de duplicidade - userInfo vazio, sem NSUnderlyingErrorKey. A classificação funciona sem correspondência de string. |
| 1007 | CredentialImport | iOS 18.2 | Importação de credencial falhou. |
| 1008 | CredentialExport | iOS 18.2 | Exportação de credencial falhou. |
| 1009 | PreferSignInWithApple | iOS 26 | Usuário prefere Iniciar Sessão com a Apple em vez de chave de acesso. Novo no iOS 26. |
| 1010 | DeviceNotConfiguredForPasskeyCreation | iOS 26 | Dispositivo sem senha ou configuração de iCloud Keychain. Bug conhecido no simulador do iOS 26: retorna 1010 mesmo quando a configuração está correta (não reproduzível em dispositivos físicos). |
A distinção mais importante para produção: desde o iOS 18, credenciais duplicadas retornam seu próprio código de erro 1006 (MatchedExcludedCredential). No iOS 17 e anteriores, as credenciais duplicadas ficavam ocultas dentro do código 1004 (Failed). No iOS 18+, a distinção é estrutural (código de erro diferente), não textual.
Erros de tempo de execução comuns (referência de nível de log):
Essas mensagens aparecem em localizedDescription ou em userInfo para cenários de falha específicos. Use-os para pesquisas de log e depuração, não para classificação programática.
| Mensagem (localização em inglês) | Código subjacente | Notas |
|---|---|---|
Application with identifier <TeamID.BundleID> is not associated with domain X | 1004 (Failed) | O entitlement Associated Domains do aplicativo não corresponde à parte confiável. Corrija o arquivo apple-app-site-association no seu servidor. |
Couldn't communicate with a helper application. | 1004 (Failed) | A extensão do provedor de credenciais não respondeu. Transitório - repetir é apropriado. |
Request already in progress for specified application identifier. | 1004 (Failed) | Uma solicitação ASAuthorization duplicada foi acionada enquanto uma estava pendente. Condição de corrida no aplicativo. |
Stolen Device Protection is enabled and biometry is required. | 1004 (Failed) | Stolen Device Protection do iOS 17+ bloqueia auth biométrica em locais não familiares. Não acionável por desenvolvedores, mas vale a pena informar ao usuário. |
(AuthenticationServicesCore.ASCABLEClient.ClientError error 2.) | Domínio separado | Falha no handshake Bluetooth para autenticação entre dispositivos (hybrid/CABLE). |
(AuthenticationServicesCore.ASCABLEClient.ClientError error 3.) | Domínio separado | Falha de conexão Bluetooth para autenticação entre dispositivos. |
Mensagens "nenhuma credencial" localizadas (código 1005):
Quando preferImmediatelyAvailableCredentials está definido e não há chave de acesso, o iOS retorna o código 1005 (NotInteractive) com uma mensagem localizada no idioma do dispositivo do usuário. Isto é exclusivo dos aplicativos nativos - os navegadores da web nunca expõem esse sinal. A mensagem sempre começa com A operação não pôde ser concluída. seguida do texto localizado:
| Idioma | Mensagem |
|---|---|
| Chinês (Simplificado) | 没有可用于登录的凭证。 |
| Vietnamita | Không có sẵn thông tin để đăng nhập. |
| Árabe | لا تتوفر بيانات اعتماد لتسجيل الدخول. |
| Espanhol | No hay ninguna credencial disponible para iniciar sesión. |
| Chinês (Tradicional) | 沒有可用於登入的憑證。 |
| Coreano | 로그인을 위한 자격 증명이 없습니다. |
| Francês (Canadá) | Aucun identifiant disponible pour la connexion. |
| Português (Brasil) | Nenhuma credencial disponível para login. |
| Francês (França) | Aucune information d'identification n'est disponible pour procéder à la connexion. |
| Tailandês | ไม่มีข้อมูลประจำตัวสำหรับเข้าสู่ระบบ |
| Italiano | Non ci sono credenziali disponibili per l'accesso. |
| Holandês | Geen inloggegevens beschikbaar. |
| Japonês | ログイン用の資格情報がありません。 |
| Turco | Oturum açmak için kullanılabilecek kimlik bilgisi yok. |
Os dispositivos de localização em inglês normalmente resolvem "nenhuma credencial" no nível da API antes que o framework ASAuthorization retorne um erro localizado, e é por isso que nenhuma variante em inglês aparece acima. Programaticamente, compare sempre o código 1005 em vez de analisar essas strings.
O Android apresenta os erros das chaves de acesso pela API Credential Manager (androidx.credentials). As mensagens de erro incluem uma mensagem principal e frequentemente uma cause (causa) com detalhes adicionais. Em comparação com o iOS, o Android fornece tipos de erro mais estruturados e causas mais explícitas para problemas de configuração.
Cancelamento pelo usuário e detecção de credenciais:
| Erro | Notas |
|---|---|
User cancelled the operation | O usuário fechou o prompt de chave de acesso. Equivalente ao NotAllowedError. Nota: O Credential Manager também retorna User canceled the request de um caminho de código diferente - ambos são idênticos. |
Excluded credential matches existing credential | Uma chave de acesso já existe para este ID de credencial. Equivalente a InvalidStateError. Diferente do iOS, a mensagem é distinta do cancelamento de usuário. |
No create options available. | Nenhum provedor de credenciais qualificado pode tratar a solicitação de criação. Normalmente significa que o Google Play Services está desatualizado ou nenhum provedor suporta a criação de chave de acesso. |
Erros de configuração e segurança:
| Erro | Notas |
|---|---|
Passkeys not supported for this app | Digital Asset Links (assetlinks.json) ausente ou não contém a impressão digital do certificado de assinatura do aplicativo. O equivalente a SecurityError. |
Https failed: respCode=301, url=https://<domain>/.well-known/assetlinks.json | O arquivo assetlinks.json retorna um redirecionamento em vez de HTTP 200. O Android exige o arquivo na URL exata sem redirecionamentos. |
The incoming request cannot be validated | O Credential Manager não pôde verificar a solicitação em relação ao Digital Asset Links. |
RP ID cannot be validated. | A ID da parte confiável nas opções do WebAuthn não corresponde ao assetlinks.json. |
Screen lock is missing. | Nenhum PIN, padrão, ou biométrica configurada no dispositivo. As chaves de acesso exigem a verificação do usuário. O equivalente a ConstraintError. |
Cannot find an eligible account. | Nenhuma conta do Google no dispositivo é qualificada para a criação da chave de acesso (raro, normalmente para configurações corporativas personalizadas). |
Erros de plataforma e autenticador:
| Erro | Notas |
|---|---|
Unsuccessful result from folsom activity. | Falha interna do Google Play Services. "Folsom" é um componente GMS para operações de chaves de acesso. Transitório - repetir é apropriado. |
Can't find the proper key to decrypt the private key from WebauthnCredentialSpecifics. | Uma chave de acesso sincronizada existe, mas o dispositivo não pode descriptografar sua chave privada. O estado de sincronização do Google Password Manager é inconsistente - a credencial foi sincronizada a partir de outro dispositivo, mas a chave de descriptografia não está disponível. Não acionável por desenvolvedores. |
Operation was interrupted (cause: The UI was interrupted - please try again.) | A interface do Credential Manager foi interrompida por outra atividade (chamada recebida, rotação da tela, aplicativo em segundo plano). O equivalente ao AbortError. |
Unknown credential error | Erro genérico quando nenhum tipo de erro específico se aplica. Normalmente transitório. |
timeout (cause: Canceled) | A operação do Credential Manager expirou antes que o usuário concluísse a verificação biométrica. |
O diagrama a seguir mostra como todas as camadas discutidas acima - Infraestrutura, Ambiente, Tipo de operação, Classificação e Detecção - se conectam de ponta a ponta. É o modelo mental que você deve ter em mente ao projetar seu rastreamento de erros.
A descoberta principal: um error.name bruto só faz sentido quando você sabe qual camada do Ambiente o produziu, qual Operação estava em execução e se o erro era Esperado ou Inesperado. As seções a seguir cobrem o que registrar e como agir.
A maior parte da classificação de erros neste artigo pode ser feita usando apenas sinais do lado do cliente. Um SDK de observabilidade focado no frontend captura contexto suficiente para classificar a grande maioria dos erros do WebAuthn. É também assim que o SDK de observabilidade do Corbado é arquitetado: a camada do cliente trata da atribuição do erro, do tempo de resposta, do contexto da operação e da detecção da plataforma. O registro no servidor adiciona uma segunda camada para falhas que apenas o back-end pode ver.
O requisito principal: cada tentativa deve ser conectável de ponta a ponta. Um ID de correlação compartilhado (por exemplo, auth_flow_id) conecta o contexto do lado do cliente ao resultado da verificação do servidor.
| Sinal | Por que importa |
|---|---|
error.name + categoria de motivo normalizada | Erro bruto do navegador + sua classificação |
| Tipo de operação | Conditional UI, login modal, criação manual, criação condicional, adição automática. CDA (Autenticação Entre Dispositivos) é uma parte complexa própria. |
| Contexto do Ambiente Completo | SO + Versão, Navegador + Versão, Marca/Modelo de Hardware, Configurações do Autenticador (ex., GPM habilitado?) |
| Contexto do Autenticador / gerenciador de credenciais | Extensão e problemas do provedor |
| Tempo até o erro a partir do início da operação | Rejeição imediata (<1s) vs cancelamento pelo usuário (1 a 15s) vs tempo limite (30s+) |
| Rede / Status da Conexão | Erros de rede muitas vezes se manifestam como erros de cliente. Rastrear se o usuário estava offline e enfileirar registros para enviar quando a conectividade for restaurada. |
| Se a UI QR/híbrida apareceu | Falha local vs entre dispositivos |
ID de correlação (auth_flow_id) | Vincular com os registros do servidor |
As falhas de verificação do servidor ocorrem depois que o navegador retorna uma credencial e um desafio assinado. Esses devem ser erros estruturados com códigos explícitos, e não misturados na mesma categoria dos nomes de DOMException do lado do cliente. Veja: implementação do servidor WebAuthn.
| Sinal | Por que importa |
|---|---|
| Incompatibilidade de desafio / desafio expirado | Problemas de tempo de sessão ou repetição |
| Incompatibilidade de Origem / ID de RP | Bugs de configuração de vários domínios |
| Assinatura inválida / credencial não encontrada | Credencial excluída ou corrompida. Caso comum: login com Conditional UI usando uma chave de acesso que o usuário já apagou no servidor. Use a API Signal para manter as listas de credenciais de cliente e servidor sincronizadas. |
| Incompatibilidade do identificador de usuário (user handle) | Problemas de mapeamento de contas |
ID de correlação (auth_flow_id) | Vincular com o contexto do lado do cliente |
Se você quer um modelo de funil completo (desistências por etapa e conversão entre as etapas), veja: telemetria de chaves de acesso para entender as desistências.
Assine nosso Substack de passkeys para receber as últimas novidades.
Com esses dados em vigor, a conclusão torna-se simples: a maioria dos "erros" torna-se correções de interface do usuário, correções de cobertura ou correções de configuração. Mas construir e manter esta classificação você mesmo é um trabalho contínuo significativo.
A lista de verificação de log acima captura sinais brutos. Na produção em escala, o error.name isolado não é suficiente. Construir esta classificação por conta própria é um trabalho contínuo significativo: as mensagens de erro mudam a cada lançamento de navegador e SO, os provedores de gerenciamento de senhas enviam atualizações que alteram o comportamento da cerimônia e novas assinaturas de erro aparecem a cada lançamento de recurso.
error.name isolado não é suficiente#O mesmo NotAllowedError pode significar seis coisas diferentes, dependendo de três dimensões que os navegadores não separam para você:
| Dimensão | O que os navegadores fornecem | O que você realmente precisa | Exemplo |
|---|---|---|---|
| Contexto da operação | NotAllowedError | Foi um Conditional UI, login modal, criação manual, criação condicional, ou adição automática? | O Android retorna o mesmo "erro desconhecido" para um descarte de login (esperado) e uma falha de criação (inesperada) |
| Tempo | Sem dados de duração | Rejeição imediata (<1s) vs cancelamento pelo usuário (1 a 15s) vs tempo limite (30s+) | 200ms = rejeição do ambiente; 5s = usuário viu a caixa de diálogo e cancelou; 35s = tempo limite |
| Plataforma + autenticador | error.name genérico | SO, navegador, versão, gerenciador de credenciais para cada erro | "usuário fechou o diálogo" no Chrome e "preenchimento automático não disponível" no Safari aparecem como NotAllowedError |
Este é o problema que o SDK de observabilidade do Corbado foi projetado para resolver. É uma integração frontend leve que se sobrepõe à sua implementação de chaves de acesso existente, funciona com qualquer servidor WebAuthn e qualquer IDP, e classifica automaticamente cada erro WebAuthn em todas as três dimensões:
| Capacidade | O que ele faz |
|---|---|
| Atribuição de erro | Captura SO, versão do SO, navegador, versão do navegador e autenticador a cada tentativa de cerimônia |
| Modo de operação | Conecta cada erro à operação específica (Conditional UI, login modal, criação manual, criação condicional, adição automática) para que o mesmo NotAllowedError se resolva em diferentes causas raiz |
| Tempo desde o início | Registra a duração desde o início da cerimônia para distinguir rejeições imediatas, cancelamentos de usuários e limites de tempo sem precisar adivinhar |
| Classificação inteligente de erros | Corresponde ao contexto completo do erro (não apenas o nome), normalizando nos vários Ambientes (SO, Hardware, Configurações). Prioriza grupos de erros distintos como CDA vs. Local, e distingue erros Esperados (Aborto pelo Usuário) de Inesperados (Falha do Sistema). |
| Fragmentação de gerenciador de senhas | Detecta quando extensões de gerenciadores de credenciais (Bitwarden, 1Password, LastPass) interceptam as cerimônias e retornam respostas não padronizadas, separando as falhas causadas pelas extensões das falhas da plataforma |
Esta é a camada Observe: visibilidade do que está acontecendo, sem precisar mudar sua implementação.
A interface de gestão do Corbado suporta dois caminhos de investigação:
De cima para baixo (do painel à causa raiz):
De baixo para cima (de padrões de erro a impactos):
Ambos os caminhos convergem: o de cima para baixo indica que algo está errado e o de baixo para cima diz por que. O Assistente de Análise com IA conecta ambos ao permitir que você faça perguntas utilizando linguagem natural acerca dos dados de erros e métricas de adoção.
As equipes que desejam agir sobre estes sinais podem avançar para a funcionalidade Adopt, a qual incorpora inteligência de chaves de acesso para proteger cerimônias automaticamente, otimizar prompts de inscrição e consertar os estados corrompidos das chaves de acesso. Para ambientes regulamentados ou implementações em larga escala, a funcionalidade Enterprise traz alojamento para inquilino único, integração SIEM e configuração compatível com a PSD2.
Obtenha um whitepaper gratuito de passkeys para empresas.
Os nomes de erro do WebAuthn não são um veredito. Eles são pistas - e só se tornam acionáveis quando você os conecta ao tipo de operação, ao tempo e ao contexto da plataforma.
NotAllowedError), ciclo de vida ou concorrência da aplicação (AbortError), contexto/configuração de segurança (SecurityError) ou falhas em estados e opções (InvalidStateError, ConstraintError, DataError). A grande maioria do volume provém de NotAllowedError, sendo a maior parte disso um comportamento previsível (como o usuário que dispensa o prompt).NotAllowedError? Recorra ao tempo de resposta (rejeição imediata vs cancelamento pelo utilizador vs expiração de tempo limite), uma indicação da interface QR/híbrida (incompatibilidade de disponibilidade), o contexto em que a ativação acontece pelo utilizador (especialmente em iOS/Safari) bem como o tipo da operação (se é login com Conditional UI vs login em ecrã modal vs criação de chaves de acesso vs criação condicional). Evite tratar a totalidade de NotAllowedError enquanto uma mesma modalidade de falha.error.name num login com Conditional UI é um sinal inteiramente diferente daquilo que reflete durante a criação condicional ou aquando a criação explícita da chave de acesso (no momento em que o usuário recusa as caixas de diálogo). O registro minucioso da modalidade de operação atrelado ao erro será aquilo que possibilita a transmutação do NotAllowedError vago numa rubrica executável.error.name, a natureza da operação executada, o momento exato em que a falha desponta, o tipo de trajetória a percorrer e a forma da interface QR/híbrida. Guarde ainda OS/navegador/equipamento (com as versões envolvidas), um identificador que agrupe essas propriedades (auth_flow_id) e recusas provenientes da verificação servidor tratadas num padrão rigoroso sob a forma de códigos formais.A título de duas advertências principais aplicáveis em toda linha de erros: não demonstre falhas exatas e textuais dos navegadores em causa aos utilizadores finais, ao longo do tempo procure fornecer um escape compreensível — mantenha isoladas tentativas realizadas pontualmente nos terminais sem que elas interfiram em conexões originadas por via QR ou mesmo na ponte entre dispositivos — e tudo isso, devido às discrepâncias notórias nos causadores dessas irregularidades. Escalando esses processos, sustentar a devida classificação de falhas navegando através de browsers distintos, variados graus nas ramificações dos Sistemas e provedores de chaves é um esforço exaustivo. Contemple, desse modo, a opção de utilizar um kit de SDK especializado com a capacidade de manter esse conjunto já construído.
Corbado é a Authentication Intelligence Platform para times de CIAM que rodam autenticação consumer em escala. Mostramos o que logs de IDP e ferramentas genéricas de analytics não enxergam: quais dispositivos, versões de SO, navegadores e gerenciadores de credenciais suportam passkeys, por que os registros não viram logins, onde o fluxo WebAuthn falha e quando uma atualização de SO ou navegador quebra silenciosamente o login — tudo sem substituir Okta, Auth0, Ping, Cognito ou seu IDP interno. Dois produtos: Corbado Observe adiciona observabilidade para passkeys e qualquer outro método de login. Corbado Connect entrega passkeys gerenciados com analytics integrado (junto ao seu IDP). VicRoads roda passkeys para mais de 5M de usuários com Corbado (+80% de ativação de passkey). Fale com um especialista em Passkeys →
Na web, os navegadores combinam os dois casos em um NotAllowedError por razões de privacidade, portanto não será possível estabelecer distinção com base no evento isolado. Tire proveito da duração atestando que sob o prazo limite de apenas 1 segundo trata-se de um conflito ambiental inerente ao terminal e limitações de disponibilidade. Na faixa de tempo limite contígua a um valor de até 15 segundos o veredito sugere a intenção visual por meio dos usuários frente aos parâmetros oferecidos no prompt. Em aplicações de cariz nativo iOS ou Android, utilizar preferImmediatelyAvailableCredentials antes da sua invocação lhe fornece acesso direto ao sinalizador puro traduzível por "sem credenciais disponíveis" (no iOS, código exato 1005; já no Android, equivalente no pedido de GetCredentialRequest) antes da projeção visual dos botões expostos.
Em ambientes implementados de grande magnitude focados em chaves de acesso devidamente ajustadas, ultrapassando um valor em torno de 95% do panorama assinalado por WebAuthn representam rejeições naturais inerentes ao desinteresse circunstancial vindo da parte do consumidor, deixando as questões internas por si intactas. Registrar picos sob valores unificados do error.name misturando na amostra as abstenções sem categorizar em falhas genuínas inflaciona métricas que na realidade se escondem na categoria em constante sobressalto NotAllowedError. Fracione todos esses cômputos num âmbito analítico através dos propósitos acoplados em subescalas e categorize a rejeição manual sem englobar sob constrangimentos de erro inesperado tipo SecurityError, ConstraintError e os que afetam preenchimento dos dados com relevo ao DataError.
O erro equivalente ao número iOS 1005 (NotInteractive) pressupõe que as ferramentas atreladas às credenciais passkey não correspondiam ao catálogo inerente ao aparelho perante o disparo imediato invocado com preferImmediatelyAvailableCredentials mediante diretriz explícita impulsionada no ASAuthorizationController, ocorrendo o ocultamento perante a exposição na interface visual ao utilizador. A vertente denota em si um indicativo autêntico do modelo ausente não verificável nos navegadores web graças aos fatores e garantias em volta da privacidade. Mantenha as abordagens categóricas sob esse enquadramento de números descartando correlações linguísticas baseadas no conteúdo estendido da rubrica descrita sob a chancela localizedDescription, de resto, lembre-se do fato das locuções fornecidas aos usuários provindas da base de dados baseada em Apple encontrarem-se espalhadas no mínimo em mais de trinta vertentes localizadas, e com variações imprevistas consoante as novas construções dos sistemas operacionais adjacentes.
No contexto dos mecanismos na modalidade de registro sob escrutínios condicionais, o reflexo devolvido no cômputo englobando o NotAllowedError, AbortError interligado ao InvalidStateError abrange vertentes com comportamentos regulares. Abstraia a existência em pormenor, abstendo de ressalvas as discrepâncias sem apresentar de forma alarmante num balão explícito focado a expor o evento ao utilizador sob a chancela dos equívocos de natureza errónea. É previsível em cenários abrangendo NotAllowedError quando as caixas em branco reservadas a facilitar no ato e o preenchimento não estejam abertas nem encontrem margem funcional visando atuar num plano focado ou subjacente na vista corrente; adicionalmente com relevo no cenário coberto com o aspeto do registo InvalidStateError a equivalência reside sob os trâmites do provedor em deter na sua posse o equivalente a essas chaves geradas em antecedência. Para salvaguarda frente a tentativas sem provimento ateste, antes das ocorrências se perfazerem mediante chamada direta utilizando-se do utilitário voltado a conferir getClientCapabilities(), para se guiar garantindo e confirmando as prerrogativas sob a modalidade da compatibilidade ao acionar vertentes interligadas a um estado focado e visível correspondente sem prejudicar indicadores sensíveis e volumes errôneos perante os contadores centrais.
A fim de desvendar a amplitude da temática registrando os cenários na ocorrência dos obstáculos com a viabilidade associada às ações inerentes no modelo de intervenção atrelado ao registo dos trâmites perante a invocação efetuada nos mecanismos em conformidade sob a rubrica da origem do tempo despendido face às manifestações contadas a partir do decorrer exato da modalidade operatória imposta — bem como das sub-versões na origem atrelada ao aparelho central sem descurar o panorama subjacente sob o painel principal inerente no terminal do qual é exposta a manifestação no quadro de cruzamentos com pormenores inerentes na UI enquadrada num plano em híbrido e uma credencial representativa atrelada no campo com valências numa equivalência voltada a reunir todas inter-ligações partindo dos rastros provindos e acolhidos aos processos executáveis atrelados ao plano servidor perante o back-end associado de forma paralela. Revezes e deflexões com proveniência vinda nos canais oriundos em trâmites nos processos sob as recusas na validade da assinatura base aliando isso ainda sob atestados caducos provindos sem sucesso em desvendar e encontrar identificações registadas devem integrar códigos fixos delineados nas regras que gerem os campos sem permitir sobreposições difusas acopladas com a dimensão que atrela nas diretivas nativas nos navegadores adjacentes na sintaxe base e subjacente em basear esses modelos em formato inerente ao tipo voltado à denominação provinda sob origem no espetro DOMException dos canais provindos ao lado contíguo onde reside a base de dados em volta dos eventos originários. Esse enquadramento dotado das suas qualidades acoplado perante as interações em vista agrupa essas manifestações agrupando-as na categoria a providenciar mecanismos úteis com precisões infalíveis sem a dimensão aleatória subjacente baseando apenas as suposições e o cenário em deduções baseadas na tentativa.
Veja como a Corbado se encaixa na sua implementação de passkeys e no stack de autenticação atual.
Explorar a Console
Artigos relacionados
Índice