{"record":{"id":"69bf6b1c34969ccb","repo":"spring-projects/spring-security","slug":"ex-getmessage-69bf6b","errorCode":null,"errorMessage":"<ex.getMessage()>","messagePattern":"<ex\\.getMessage\\(\\)>","errorType":"exception","errorClass":"BadCredentialsException","httpStatus":401,"severity":"error","filePath":"webauthn/src/main/java/org/springframework/security/web/webauthn/authentication/WebAuthnAuthenticationProvider.java","lineNumber":80,"sourceCode":"\t\tAssert.notNull(userDetailsService, \"userDetailsService cannot be null\");\n\t\tthis.relyingPartyOperations = relyingPartyOperations;\n\t\tthis.userDetailsService = userDetailsService;\n\t}\n\n\t@Override\n\tpublic Authentication authenticate(Authentication authentication) throws AuthenticationException {\n\t\tWebAuthnAuthenticationRequestToken webAuthnRequest = (WebAuthnAuthenticationRequestToken) authentication;\n\t\ttry {\n\t\t\tPublicKeyCredentialUserEntity userEntity = this.relyingPartyOperations\n\t\t\t\t.authenticate(webAuthnRequest.getWebAuthnRequest());\n\t\t\tString username = userEntity.getName();\n\t\t\tUserDetails userDetails = this.userDetailsService.loadUserByUsername(username);\n\t\t\tCollection<GrantedAuthority> authorities = new HashSet<>(userDetails.getAuthorities());\n\t\t\tauthorities.add(FactorGrantedAuthority.fromAuthority(AUTHORITY));\n\t\t\treturn new WebAuthnAuthentication(userEntity, authorities);\n\t\t}\n\t\tcatch (RuntimeException ex) {\n\t\t\tthrow new BadCredentialsException(ex.getMessage(), ex);\n\t\t}\n\t}\n\n\t@Override\n\tpublic boolean supports(Class<?> authentication) {\n\t\treturn WebAuthnAuthenticationRequestToken.class.isAssignableFrom(authentication);\n\t}\n\n}\n","sourceCodeStart":62,"sourceCodeEnd":90,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/webauthn/src/main/java/org/springframework/security/web/webauthn/authentication/WebAuthnAuthenticationProvider.java#L62-L90","documentation":"WebAuthnAuthenticationProvider.authenticate() catches any RuntimeException from loading the user or building the WebAuthn authentication result and rethrows it as BadCredentialsException carrying the original message (the message here is ex.getMessage()). It deliberately masks internal exceptions as invalid credentials, so the actual cause is in the wrapped exception.","triggerScenarios":"The underlying UserDetailsService or WebAuthn entity lookup throws a RuntimeException during authentication — e.g. UsernameNotFoundException, a data-access failure, or a null/misconfigured userDetailsService bean — during a WebAuthn assertion attempt.","commonSituations":"Username encoded in userHandle not found in the database; user deleted between registration and login; database down; UserDetailsService miswired in the WebAuthnAuthenticationProvider configuration.","solutions":["Inspect the cause exception of the BadCredentialsException (ex.getCause()) to identify the real RuntimeException thrown by loadUserByUsername or credential verification.","Verify the WebAuthn user exists in the credential/user records for the given username and that the UserDetailsService bean is correctly configured.","Fix the underlying data/infrastructure issue (missing user record, DB connectivity) rather than catching BadCredentialsException as a wrong-password signal."],"exampleFix":"// before\ntry {\n    auth = provider.authenticate(token);\n} catch (BadCredentialsException e) {\n    log.warn(\"bad credentials\");\n}\n// after\ntry {\n    auth = provider.authenticate(token);\n} catch (BadCredentialsException e) {\n    log.warn(\"bad credentials, cause=\" + e.getCause(), e); // inspect real reason\n    throw e;\n}","handlingStrategy":"try-catch","validationCode":"// before authenticating, verify the user record exists\nUserDetails u = userDetailsService.loadUserByUsername(username); // throws UsernameNotFoundException if absent\n","typeGuard":null,"tryCatchPattern":"try {\n    Authentication auth = authenticationManager.authenticate(token);\n} catch (BadCredentialsException e) {\n    log.debug(\"WebAuthn auth failed: {}\", e.getCause() != null ? e.getCause().toString() : e.getMessage());\n    throw new BadCredentialsException(\"authentication failed\");\n}\n","preventionTips":["Always inspect getCause() — the provider masks the real RuntimeException in the message","Keep user and credential records consistent (cascade deletes when removing users)","Monitor for data-access exceptions appearing as BadCredentialsException — they indicate infra issues, not bad credentials","Test the full flow with a deleted user to ensure graceful failure"],"tags":["webauthn","authentication","user-details","java"],"backgroundTag":"user-not-found","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}