apereo/cas · warning
Lookup of datasource
Error message
Lookup of datasource [{}] failed due to [{}]. Back to JPA properties. What it means
JpaBeans.newDataSource first tries to resolve the configured datasource name via JNDI (JndiDataSourceLookup). If the lookup throws DataSourceLookupFailureException - the name is not bound in the container's JNDI tree - it logs this WARN and falls back to building a HikariDataSource from the JPA properties (driver class, URL, user, password). It is a recoverable fallback, not a fatal error; the returned pool just uses local JDBC settings instead of the container-managed datasource.
Solutions
- Declare the JNDI datasource in the servlet container (context.xml Resource, server datasource config) so the lookup succeeds
- Remove/clear the dataSourceName property so CAS skips the JNDI attempt and builds the Hikari pool directly from JPA properties
- Ensure jpaProperties (url, driverClass, user, password) are fully populated since they are used for the fallback
- Verify the exact JNDI name string matches the container binding, including java:comp/env prefixing behavior
Example fix
// before cas.authn.jpa.dataSourceName=jdbc/casDb // after cas.authn.jpa.url=jdbc:postgresql://db:5432/cas cas.authn.jpa.driverClass=org.postgresql.Driver cas.authn.jpa.user=cam cas.authn.jpa.password=secret
Defensive patterns
Strategy: fallback
Validate before calling
try { new javax.naming.InitialContext().lookup("java:comp/env/jdbc/casDb"); } catch (NamingException e) { System.out.println("JNDI ds missing - ensure JPA url/driver/user/password are set"); } Try / catch
try { dataSource = new InitialContext().lookup("java:comp/env/jdbc/casDb"); } catch (NamingException e) { LOGGER.warn("JNDI lookup failed; using Hikari from JPA properties", e); dataSource = buildHikari(jpaProperties); } Prevention
- Only set dataSourceName when deploying to a container that actually binds the JNDI resource
- Keep JPA url/driverClass/user/password configured as fallback even when using JNDI
- Match JNDI names exactly between CAS config and container resource declarations
- Watch logs at startup for the fallback warning to know which pool is active
When it happens
Trigger: Configuring a JPA module (cas.authn.jpa, tickets-jpa, services-jpa, etc.) with a dataSourceName while running outside a servlet container that exposes that JNDI resource; JNDI name typo or missing <Resource>/resource-ref declaration; deploying the CAS WAR standalone (embedded container) where no JNDI datasource is provisioned.
Common situations: Running CAS via embedded Tomcat/Jetty in dev where no JNDI datasource is bound; moving an app from app-server deployment to standalone and forgetting to remove dataSourceName; JNDI binding present only after datasource resource is declared in server config.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- Cannot save a resource set with inconsistent scopes.
- No expiration policy was found for ticket state
- LoggingUtils.warn(LOGGER, e)
- Token [ ] has expired
- No registered service is found to match
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/6e861df13a49c18e.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-jpa-util/src/main/java/org/apereo/cas/configuration/support/JpaBeans.java:118
* <p>
* If user wants to do lookup as resource, they may include {@code java:/comp/env}
* in {@code dataSourceName} and put resource reference in web.xml
* otherwise {@code dataSourceName} is used as JNDI name.
*
* @param jpaProperties the jpa properties
* @return the data source
*/
public CloseableDataSource newDataSource(final AbstractJpaProperties jpaProperties) {
val dataSourceName = jpaProperties.getDataSourceName();
if (StringUtils.isNotBlank(dataSourceName)) {
try {
val dsLookup = new JndiDataSourceLookup();
dsLookup.setResourceRef(false);
val containerDataSource = dsLookup.getDataSource(dataSourceName);
return new DefaultCloseableDataSource(containerDataSource);
} catch (final DataSourceLookupFailureException e) {
LOGGER.warn("Lookup of datasource [{}] failed due to [{}]. Back to JPA properties.", dataSourceName, e.getMessage());
}
}
val bean = new HikariDataSource();
FunctionUtils.doIfNotBlank(jpaProperties.getDriverClass(), _ -> bean.setDriverClassName(jpaProperties.getDriverClass()));
val url = SpringExpressionLanguageValueResolver.getInstance().resolve(jpaProperties.getUrl());
bean.setJdbcUrl(url);
bean.setUsername(jpaProperties.getUser());
bean.setPassword(jpaProperties.getPassword());
val poolSettings = jpaProperties.getPool();
FunctionUtils.doUnchecked(_ -> bean.setLoginTimeout((int) Beans.newDuration(poolSettings.getMaxWait()).toSeconds()));
bean.setMaximumPoolSize(poolSettings.getMaxSize());
bean.setMinimumIdle(poolSettings.getMinSize());
bean.setIdleTimeout(Beans.newDuration(jpaProperties.getIdleTimeout()).toMillis());
bean.setLeakDetectionThreshold(Beans.newDuration(jpaProperties.getLeakThreshold()).toMillis());
bean.setInitializationFailTimeout(jpaProperties.getFailFastTimeout());View on GitHub (pinned to e7288fc434)