apereo/cas · error · AccountNotFoundException

Encoded password is null.

Error message

Encoded password is null.

What it means

transformPassword throws AccountNotFoundException when the configured PasswordEncoder encodes the password into a null/empty string. The raw password existed, but the encoding step produced nothing, so CAS reports the account as not found rather than continuing with an unusable encoded value.

Solutions

  1. Inspect the configured PasswordEncoder; ensure its encode() never returns null/empty — return the input or throw a clear error instead.
  2. Test the encoder directly in a unit test with the same password value.
  3. If using a Groovy/scripted encoder, add explicit return statements and logging inside the script.
  4. Verify the encoder bean binding on the handler (passwordEncoder field) points to the intended implementation.
  5. Check for character-encoding/array-conversion issues in custom encoder code.

Example fix

// before
public String encode(CharSequence raw) {
    try { return sha256(raw); } catch (Exception e) { return null; }
}
// after
public String encode(CharSequence raw) {
    try { return sha256(raw); } catch (Exception e) { throw new IllegalStateException("password encoding failed", e); }
}
Defensive patterns

Strategy: validation

Validate before calling

// verify your encoder before wiring it
PasswordEncoder enc = ...;
String encoded = enc.encode("sample-password");
if (StringUtils.isBlank(encoded)) { throw new IllegalStateException("PasswordEncoder must never return a blank value"); }

Try / catch

try {
    return handler.authenticate(credential, service);
} catch (AccountNotFoundException e) {
    if (e.getMessage() != null && e.getMessage().contains("Encoded password")) {
        LOGGER.error("PasswordEncoder returned a blank value; fix or replace the encoder", e);
    }
    throw new BadCredentialsAuthenticationException();
}

Prevention

When it happens

Trigger: transformPassword calls passwordEncoder.encode(userPass.toPassword()) and the result is blank — e.g. a custom PasswordEncoder whose encode() returns null, a Groovy/scripted encoder that fails silently, or an encoder misconfigured with an empty format.

Common situations: Custom PasswordEncoder implementation bug (returning null on certain inputs); scripted encoder throwing internally and being swallowed; char array-to-string conversion wiping the value; encoder bean wired to the wrong implementation after a config refactor.

Related errors


AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08). Data as JSON: /api/errors/507668b091db1755. Report an issue: GitHub.

Appendix: source

Thrown at core/cas-server-core-authentication-api/src/main/java/org/apereo/cas/authentication/handler/support/AbstractUsernamePasswordAuthenticationHandler.java:88

    @Override
    protected AuthenticationHandlerExecutionResult doAuthentication(final Credential credential, final Service service) throws Throwable {
        val originalUserPass = (UsernamePasswordCredential) credential;
        val userPass = new UsernamePasswordCredential();
        FunctionUtils.doUnchecked(_ -> BeanUtils.copyProperties(userPass, originalUserPass));
        transformUsername(userPass);
        transformPassword(userPass);
        LOGGER.debug("Attempting authentication internally for transformed credential [{}]", userPass);
        return authenticateUsernamePasswordInternal(userPass, originalUserPass.toPassword());
    }

    protected void transformPassword(final UsernamePasswordCredential userPass) throws FailedLoginException, AccountNotFoundException {
        if (StringUtils.isBlank(userPass.toPassword())) {
            throw new FailedLoginException("Password is null.");
        }
        LOGGER.debug("Attempting to encode credential password via [{}] for [{}]", passwordEncoder.getClass().getName(), userPass.getUsername());
        val transformedPsw = passwordEncoder.encode(userPass.toPassword());
        if (StringUtils.isBlank(transformedPsw)) {
            throw new AccountNotFoundException("Encoded password is null.");
        }
        userPass.assignPassword(transformedPsw);
    }
    
    /**
     * Authenticates a username/password credential by an arbitrary strategy with extra parameter original credential password before
     * encoding password. Override it if implementation need to use original password for authentication.
     *
     * @param credential       the credential object bearing the transformed username and password.
     * @param originalPassword original password from credential before password encoding
     * @return AuthenticationHandlerExecutionResult resolved from credential on authentication success or null if no principal could be resolved from the credential.
     * @throws Throwable the throwable
     */
    protected abstract AuthenticationHandlerExecutionResult authenticateUsernamePasswordInternal(
        UsernamePasswordCredential credential,
        @Nullable String originalPassword) throws Throwable;

    /**

View on GitHub (pinned to e7288fc434)