apereo/cas · error · FailedLoginException
[e.getMessage()]
Error message
[e.getMessage()]
What it means
The handler wraps the whole authentication attempt in catch (Throwable) and rethrows FailedLoginException(e.getMessage()). Any database-level failure (SQL syntax error, connection failure, driver missing, NPE) surfaces as this generic failed-login message with the original message text.
Solutions
- Read the logged stack trace via LoggingUtils output to identify the root cause.
- Test the datasource connectivity and run the generated SQL directly in the DB.
- Validate cas.authn.jdbc.search[] properties (sql, table, fields) and the JDBC driver dependency.
- Replace generic handling by checking DB health and configuration before enabling this handler.
Example fix
// before: sql missing FROM table cas.authn.jdbc.search[0].sql=SELECT COUNT(*) FROM WHERE username=? AND password=? // after cas.authn.jdbc.search[0].sql=SELECT COUNT(*) FROM users WHERE username=? AND password=?
Defensive patterns
Strategy: try-catch
Validate before calling
// health-check the datasource before attempting auth
jdbcTemplate.queryForObject("SELECT 1", Integer.class); Try / catch
try { result = handler.authenticate(credential); }
catch (FailedLoginException e) {
Throwable root = ExceptionUtils.getRootCause(e);
log.error("Auth failed: {}", root == null ? e.getMessage() : root.getMessage());
} Prevention
- Enable debug logging for the handler to capture the root stack trace.
- Validate SQL syntax in a DB console before deploying config.
- Keep the JDBC driver on the classpath and connection pool tested at startup.
When it happens
Trigger: Any Throwable escaping queryForObject: DataAccessException from a broken SQL string, DataSource connectivity problems, NullPointerException on misconfigured properties, ClassCastException on unexpected count types.
Common situations: Typo in cas.authn.jdbc.search[].sql; DB down or network blocked; JDBC driver not on classpath; jdbcTemplate/datasource bean misconfiguration.
Understand the failure class
Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.
Related errors
- [e.getMessage()]
- [username] not found with SQL query
- Multiple records found for [username]
- [username] not found with SQL query.
- Principal attribute [
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/ca8f0f93b87e3800.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-jdbc-authentication/src/main/java/org/apereo/cas/jdbc/SearchModeSearchDatabaseAuthenticationHandler.java:54
protected AuthenticationHandlerExecutionResult authenticateUsernamePasswordInternal(
final UsernamePasswordCredential credential, final String originalPassword) throws Throwable {
val sql = "SELECT COUNT('x') FROM ".concat(properties.getTableUsers())
.concat(" WHERE ")
.concat(properties.getFieldUser())
.concat(" = ? AND ")
.concat(properties.getFieldPassword()).concat("= ?");
val username = credential.getUsername();
try {
LOGGER.debug("Executing SQL query [{}]", sql);
val count = getJdbcTemplate().queryForObject(sql, Integer.class, username, credential.toPassword());
if (count == null || count == 0) {
throw new FailedLoginException(username + " not found with SQL query.");
}
val principal = principalFactory.createPrincipal(username);
return createHandlerResult(credential, principal, new ArrayList<>());
} catch (final Throwable e) {
LoggingUtils.error(LOGGER, e);
throw new FailedLoginException(e.getMessage());
}
}
}
View on GitHub (pinned to e7288fc434)