apereo/cas · error · FailedLoginException

[e.getMessage()]

Error message

[e.getMessage()]

What it means

BindModeSearchDatabaseAuthenticationHandler authenticates by opening a JDBC connection with the username/password as bind credentials. Any Throwable while establishing or using the connection (bad credentials, unreachable DB, driver issues) is converted into FailedLoginException whose message is the original exception's message.

Solutions

  1. Read the embedded message to identify the root cause (auth failure vs connectivity)
  2. Confirm the username/password are valid database credentials directly via a DB client
  3. Check datasource URL/host/port/network reachability and that the JDBC driver is on the classpath
  4. If the DB lacks native password-auth connections, switch to SearchModeSearchDatabaseAuthenticationHandler (query mode) with a service account

Example fix

// before (bind mode, DB without bind auth)
cas.authn.jdbc.bind[0].url=jdbc:mysql://db:3306/users
// after (search mode with service account)
cas.authn.jdbc.query[0].sql=SELECT * FROM users WHERE username=?
cas.authn.jdbc.query[0].user=root
Defensive patterns

Strategy: try-catch

Validate before calling

// precheck connectivity before auth attempt
try (var c = dataSource.getConnection()) { /* datasource reachable */ }

Try / catch

try {
    return handler.authenticate(credential);
} catch (FailedLoginException e) {
    // inspect e.getMessage(): auth failure vs connectivity; alert on connectivity messages
}

Prevention

When it happens

Trigger: authenticateUsernamePasswordInternal fails at getDataSource().getConnection(username, password) — e.g. database rejects the bind, host/port unreachable, driver class missing — and the caught Throwable's message becomes the thrown error text.

Common situations: Wrong password (DB-level auth failure reported verbatim); database down or wrong JDBC URL/host/firewall rules; missing JDBC driver on classpath; using bind mode against a DB (like some MySQL setups) that doesn't support username/password connection auth as expected.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


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

Appendix: source

Thrown at support/cas-server-support-jdbc-authentication/src/main/java/org/apereo/cas/jdbc/BindModeSearchDatabaseAuthenticationHandler.java:44

public class BindModeSearchDatabaseAuthenticationHandler extends AbstractJdbcUsernamePasswordAuthenticationHandler<BindJdbcAuthenticationProperties> {

    public BindModeSearchDatabaseAuthenticationHandler(
        final BindJdbcAuthenticationProperties properties,
        final PrincipalFactory principalFactory, final DataSource dataSource) {
        super(properties, principalFactory, dataSource);
    }

    @Override
    protected AuthenticationHandlerExecutionResult authenticateUsernamePasswordInternal(
        final UsernamePasswordCredential credential, final String originalPassword) throws Throwable {
        val username = credential.getUsername();
        val password = credential.toPassword();
        try (val connection = getDataSource().getConnection(username, password)) {
            LOGGER.trace("Established connection to schema [{}]", connection.getSchema());
            val principal = principalFactory.createPrincipal(username);
            return createHandlerResult(credential, principal, new ArrayList<>());
        } catch (final Throwable e) {
            throw new FailedLoginException(e.getMessage());
        }
    }
}

View on GitHub (pinned to e7288fc434)