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

  1. Set cas.authn.ldap[x].ldap-url to one or more space-separated LDAP URLs (e.g. ldaps://host:636)
  2. Check for typos or unresolved placeholders in the property name
  3. Validate configuration at startup — run with debug metadata/validation to catch the missing field early
  4. 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

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


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)