spring-projects/spring-security · error · BadCredentialsException
Empty Username
Error message
Empty Username
What it means
AbstractLdapAuthenticationProvider.authenticate() rejects a UsernamePasswordAuthenticationToken whose username is null or blank by throwing BadCredentialsException('Empty Username') before any LDAP call is made. The library treats missing identity as bad credentials rather than a server error.
Source
Thrown at ldap/src/main/java/org/springframework/security/ldap/authentication/AbstractLdapAuthenticationProvider.java:75
protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
private boolean useAuthenticationRequestCredentials = true;
private GrantedAuthoritiesMapper authoritiesMapper = new NullAuthoritiesMapper();
protected UserDetailsContextMapper userDetailsContextMapper = new LdapUserDetailsMapper();
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
Assert.isInstanceOf(UsernamePasswordAuthenticationToken.class, authentication,
() -> this.messages.getMessage("LdapAuthenticationProvider.onlySupports",
"Only UsernamePasswordAuthenticationToken is supported"));
UsernamePasswordAuthenticationToken userToken = (UsernamePasswordAuthenticationToken) authentication;
String username = userToken.getName();
String password = (String) authentication.getCredentials();
if (!StringUtils.hasLength(username)) {
throw new BadCredentialsException(
this.messages.getMessage("LdapAuthenticationProvider.emptyUsername", "Empty Username"));
}
if (!StringUtils.hasLength(password)) {
throw new BadCredentialsException(
this.messages.getMessage("AbstractLdapAuthenticationProvider.emptyPassword", "Empty Password"));
}
Assert.notNull(password, "Null password was supplied in authentication token");
DirContextOperations userData = doAuthentication(userToken);
UserDetails user = this.userDetailsContextMapper.mapUserFromContext(userData, authentication.getName(),
loadUserAuthorities(userData, authentication.getName(), password));
return createSuccessfulAuthentication(userToken, user);
}
protected abstract DirContextOperations doAuthentication(UsernamePasswordAuthenticationToken auth);
protected abstract Collection<? extends GrantedAuthority> loadUserAuthorities(DirContextOperations userData,
String username, String password);
View on GitHub (pinned to 96852e8860)
Solutions
- Validate the username is non-blank in your controller/filter before building the authentication token.
- Return a friendly client-side validation error instead of hitting the AuthenticationManager.
- If the empty value comes from form binding, configure the binder/filter to reject blank fields early.
- Ensure you are not accidentally passing credentials as the principal (wrong constructor argument order).
Example fix
// before
Authentication auth = new UsernamePasswordAuthenticationToken(request.getParameter("user"), request.getParameter("pass"));
manager.authenticate(auth); // Empty Username
// after
String user = request.getParameter("user");
if (user == null || user.isBlank()) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "username is required");
}
Authentication auth = new UsernamePasswordAuthenticationToken(user, request.getParameter("pass"));
manager.authenticate(auth); Defensive patterns
Strategy: validation
Validate before calling
if (username == null || username.isBlank()) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "username is required");
} Type guard
static boolean hasUsername(UsernamePasswordAuthenticationToken t) {
return t != null && t.getName() != null && !t.getName().isBlank();
} Try / catch
try {
return authManager.authenticate(token);
} catch (BadCredentialsException e) {
if ("Empty Username".equals(e.getMessage())) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "username is required");
}
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "invalid credentials");
} Prevention
- Enforce required-field validation at the controller/DTO layer before authentication.
- Add @NotBlank constraints on login DTO fields.
- Never construct authentication tokens from unvalidated request parameters.
- Check constructor argument order (principal first, credentials second).
When it happens
Trigger: Submitting an Authentication to an LdapAuthenticationProvider-backed AuthenticationManager where authentication.getName() is empty — e.g. a login form posted with an empty username field, or a custom Authentication token constructed with a null/blank principal.
Common situations: Frontend allowed empty form submission, API clients omitting the username field in a JSON login payload, custom filters creating UsernamePasswordAuthenticationToken without validating the principal, or whitespace-only input.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/78169c7281b0a945.
Report an issue: GitHub.