apereo/cas · error · IllegalArgumentException
LDAP url cannot be empty/blank
Error message
LDAP url cannot be empty/blank
What it means
LdapUtils.newLdaptiveConnectionConfig validates that AbstractLdapProperties.getLdapUrl() is non-blank before building an ldaptive ConnectionConfig; an empty URL would otherwise produce a connection factory that cannot connect anywhere. It throws IllegalArgumentException naming the problem.
Solutions
- Set cas.authn.ldap[x].ldap-url to one or more space-separated LDAP URLs (e.g. ldaps://host:636)
- Check for typos or unresolved placeholders in the property name
- Validate configuration at startup — run with debug metadata/validation to catch the missing field early
- If URLs are supplied per-environment, provide them in the environment's overlay/profile
Example fix
// before cas.authn.ldap[0].ldap-url= // after cas.authn.ldap[0].ldap-url=ldaps://directory.example.org:636
Defensive patterns
Strategy: validation
Validate before calling
if (props == null || props.getLdapUrl() == null || props.getLdapUrl().isBlank()) {
throw new IllegalStateException("cas.authn.ldap[x].ldap-url must be set before building a connection");
} Try / catch
try {
ConnectionConfig cc = LdapUtils.newLdaptiveConnectionConfig(props);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("LDAP url cannot be empty/blank")) {
// fail config load early with a clear message about the missing ldap-url
}
} Prevention
- Always set ldap-url first in every ldap[x] block
- Check for key typos and unresolved ${placeholders} in YAML/properties
- Add a startup config sanity check for required ldap fields
- Use spring-configuration-metadata / IDE validation to catch missing required keys
When it happens
Trigger: Building a ConnectionConfig/connection factory from LDAP properties where cas.authn.ldap[x].ldap-url (or the corresponding setLdapUrl) is null, empty, or whitespace — e.g. the property block was added but the URL key was never set.
Common situations: Typo in the YAML/properties key (ldapUrl vs ldap-url) so the field stays null; environment-specific config overlay omitted ldap-url; constructing AbstractLdapProperties programmatically without setLdapUrl; placeholder like ${ldap.host} unresolved to empty.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- Base dn cannot be empty/blank for authenticated/anonymous…
- User filter cannot be empty/blank for…
- Principal id attribute is not found for [principalAttr]
- Multiple principal values are not allowed: [principalAttr]
- Could not locate an LDAP entry for [filter] and base DN…
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/bf56c06f22b38313.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-ldap-core/src/main/java/org/apereo/cas/util/LdapUtils.java:540
+ "set the pool passivator setting to one of [{}]",
props.getPoolPassivator(), props.getLdapUrl(), values);
}
}
}
LOGGER.debug("Initializing LDAP connection pool for [{}] and bindDn [{}]", props.getLdapUrl(), props.getBindDn());
pooledCf.initialize();
return pooledCf;
}
/**
* New connection config connection config.
*
* @param properties the ldap properties
* @return the connection config
*/
public static ConnectionConfig newLdaptiveConnectionConfig(final AbstractLdapProperties properties) {
if (StringUtils.isBlank(properties.getLdapUrl())) {
throw new IllegalArgumentException("LDAP url cannot be empty/blank");
}
LOGGER.debug("Creating LDAP connection configuration for [{}]", properties.getLdapUrl());
val connectionConfig = new ConnectionConfig();
val urls = properties.getLdapUrl().contains(" ")
? properties.getLdapUrl()
: String.join(" ", properties.getLdapUrl().split(","));
LOGGER.debug("Transformed LDAP urls from [{}] to [{}]", properties.getLdapUrl(), urls);
connectionConfig.setLdapUrl(urls);
connectionConfig.setUseStartTLS(properties.isUseStartTls());
connectionConfig.setConnectTimeout(Beans.newDuration(properties.getConnectTimeout()));
connectionConfig.setResponseTimeout(Beans.newDuration(properties.getResponseTimeout()));
if (StringUtils.isNotBlank(properties.getConnectionStrategy())) {
val strategy = AbstractLdapProperties.LdapConnectionStrategy.valueOf(properties.getConnectionStrategy());
switch (strategy) {View on GitHub (pinned to e7288fc434)