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

  1. Ensure the username parameter is present and non-empty before invoking the handler; validate at the webflow/form level.
  2. Check that the credential extractor maps the correct request parameter to Credential.getId().
  3. Fix custom Credential construction to always supply a non-blank id.
  4. Configure client-side / webflow validation to reject blank usernames before authentication.
  5. 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

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


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)