{"record":{"id":"fc81be4a137bc273","repo":"spring-projects/spring-security","slug":"bad-credentials-fc81be","errorCode":null,"errorMessage":"Bad credentials","messagePattern":"Bad credentials","errorType":"exception","errorClass":"BadCredentialsException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/springframework/security/authentication/dao/DaoAuthenticationProvider.java","lineNumber":85,"sourceCode":"\tprivate volatile @Nullable String userNotFoundEncodedPassword;\n\n\tprivate final UserDetailsService userDetailsService;\n\n\tprivate UserDetailsPasswordService userDetailsPasswordService = UserDetailsPasswordService.NOOP;\n\n\tprivate @Nullable CompromisedPasswordChecker compromisedPasswordChecker;\n\n\tpublic DaoAuthenticationProvider(UserDetailsService userDetailsService) {\n\t\tAssert.notNull(userDetailsService, \"userDetailsService cannot be null\");\n\t\tthis.userDetailsService = userDetailsService;\n\t}\n\n\t@Override\n\tprotected void additionalAuthenticationChecks(UserDetails userDetails,\n\t\t\tUsernamePasswordAuthenticationToken authentication) throws AuthenticationException {\n\t\tif (authentication.getCredentials() == null) {\n\t\t\tthis.logger.debug(\"Failed to authenticate since no credentials provided\");\n\t\t\tthrow new BadCredentialsException(this.messages\n\t\t\t\t.getMessage(\"AbstractUserDetailsAuthenticationProvider.badCredentials\", \"Bad credentials\"));\n\t\t}\n\t\tString presentedPassword = authentication.getCredentials().toString();\n\t\tif (!this.passwordEncoder.get().matches(presentedPassword, userDetails.getPassword())) {\n\t\t\tthis.logger.debug(\"Failed to authenticate since password does not match stored value\");\n\t\t\tthrow new BadCredentialsException(this.messages\n\t\t\t\t.getMessage(\"AbstractUserDetailsAuthenticationProvider.badCredentials\", \"Bad credentials\"));\n\t\t}\n\t}\n\n\t@Override\n\tprotected void doAfterPropertiesSet() {\n\t\tAssert.notNull(this.userDetailsService, \"A UserDetailsService must be set\");\n\t}\n\n\t@Override\n\tprotected final UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication)\n\t\t\tthrows AuthenticationException {","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/core/src/main/java/org/springframework/security/authentication/dao/DaoAuthenticationProvider.java#L67-L103","documentation":"DaoAuthenticationProvider throws BadCredentialsException in additionalAuthenticationChecks when the authentication token carries no credentials at all (authentication.getCredentials() == null). Spring Security deliberately reuses a generic 'Bad credentials' message so attackers cannot distinguish a missing password from a wrong one. This is thrown after the user has been successfully looked up by username.","triggerScenarios":"Calling UsernamePasswordAuthenticationToken(username, null) and passing it to AuthenticationManager.authenticate(); an AuthenticationProvider or filter upstream that strips or never sets credentials; custom filters building the token before the servlet request parameters are read (e.g. missing Content-Type so parameters are not populated).","commonSituations":"Custom REST login endpoints where the JSON body password field is absent or null; misconfigured form login where the password parameter name was changed without updating the filter; clients sending only a username in the auth request; tests constructing the token with a null credential.","solutions":["Ensure the password is non-null when constructing UsernamePasswordAuthenticationToken(username, password) before calling AuthenticationManager.authenticate()","If credentials are supplied via HTTP, verify the request actually carries the password parameter and that the filter reading it (e.g. UsernamePasswordAuthenticationFilter) has the correct parameter names configured","When building tokens in tests or code, assert credentials are present: Assert.hasText(password, ...) before authenticate()"],"exampleFix":"// before\nAuthentication auth = new UsernamePasswordAuthenticationToken(username, null);\nauthManager.authenticate(auth);\n// after\nAssert.hasText(password, \"password is required\");\nAuthentication auth = new UsernamePasswordAuthenticationToken(username, password);\nauthManager.authenticate(auth);","handlingStrategy":"validation","validationCode":"if (password == null || password.isEmpty()) { throw new IllegalArgumentException(\"password is required\"); }\nAuthentication token = new UsernamePasswordAuthenticationToken(username, password);","typeGuard":"boolean hasCredentials(Authentication a) { return a != null && a.getCredentials() instanceof String s && !s.isEmpty(); }","tryCatchPattern":"try { return authManager.authenticate(token); } catch (BadCredentialsException e) { throw new LoginFailureException(\"Invalid username or password\"); }","preventionTips":["Always construct UsernamePasswordAuthenticationToken with a non-null password","Bind login DTOs with @NotBlank on the password field and validate before authenticating","Log a debug message on missing credentials server-side to catch misconfigured clients early"],"tags":["authentication","spring-security","bad-credentials"],"backgroundTag":"bad-credentials","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}