apereo/cas · error · AccountNotFoundException
Username is null.
Error message
Username is null.
What it means
transformUsername in AbstractPreAndPostProcessingAuthenticationHandler throws AccountNotFoundException when credential.getId() is blank. The handler refuses to run the principal-name transformer on an empty identifier, treating the credential as an unknown account rather than a generic failure.
Solutions
- Ensure the username parameter is present and non-empty before invoking the handler; validate at the webflow/form level.
- Check that the credential extractor maps the correct request parameter to Credential.getId().
- Fix custom Credential construction to always supply a non-blank id.
- Configure client-side / webflow validation to reject blank usernames before authentication.
- If blank usernames should fail differently, override transformUsername in the subclass.
Example fix
// before
val cred = new UsernamePasswordCredential("", password);
handler.authenticate(cred, null);
// after
if (StringUtils.isBlank(username)) { throw new IllegalArgumentException("username required"); }
val cred = new UsernamePasswordCredential(username, password);
handler.authenticate(cred, null); Defensive patterns
Strategy: validation
Validate before calling
// before invoking the handler
if (credential == null || StringUtils.isBlank(credential.getId())) {
throw new IllegalArgumentException("credential id (username) is required");
} Try / catch
try {
return handler.authenticate(credential, service);
} catch (AccountNotFoundException e) {
LOGGER.warn("Blank or unknown username submitted", e);
throw new BadCredentialsAuthenticationException("username required");
} Prevention
- Validate the username field client- and server-side before authentication.
- Ensure credential extractors bind the correct request parameter into Credential.getId().
- Add tests covering empty-username submissions end to end.
When it happens
Trigger: authenticate()/doAuthentication path invokes transformUsername with a credential whose id is null or empty — e.g. an empty username field in the login form that passed earlier extraction, or a custom credential constructed without setting an id.
Common situations: Blank username submitted in the login form; form binding names mismatching the extractor so id never gets populated; scripted/REST clients posting credentials with an empty principal; custom Credential subclass forgetting to set the id in its constructor.
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
- Password is null.
- Resource ID already exists in namespace .
- Authentication handler is disabled
- No user can be accepted because none is defined
- not found in backing map.
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/b4c0b71c0fbd98da.
Report an issue: GitHub.
Appendix: source
Thrown at core/cas-server-core-authentication-api/src/main/java/org/apereo/cas/authentication/handler/support/AbstractPreAndPostProcessingAuthenticationHandler.java:68
protected abstract AuthenticationHandlerExecutionResult doAuthentication(Credential credential, Service service)
throws Throwable;
protected AuthenticationHandlerExecutionResult createHandlerResult(final Credential credential,
@Nullable final Principal principal,
@Nullable final List<MessageDescriptor> warnings) {
return new DefaultAuthenticationHandlerExecutionResult(this, credential, principal, warnings);
}
protected AuthenticationHandlerExecutionResult createHandlerResult(final Credential credential,
final Principal principal) {
return new DefaultAuthenticationHandlerExecutionResult(this, credential,
principal, new ArrayList<>());
}
protected String transformUsername(final Credential credential) throws Throwable {
if (StringUtils.isBlank(credential.getId())) {
throw new AccountNotFoundException("Username is null.");
}
LOGGER.debug("Transforming credential username via [{}]", principalNameTransformer.getClass().getName());
val transformedUsername = principalNameTransformer.transform(credential.getId());
if (StringUtils.isBlank(transformedUsername)) {
throw new AccountNotFoundException("Transformed username is null.");
}
if (credential instanceof final MutableCredential mc) {
mc.setId(transformedUsername);
}
return transformedUsername;
}
}
View on GitHub (pinned to e7288fc434)