spring-projects/spring-security · error · IllegalStateException
Embedded LDAP server is not provided
Error message
Embedded LDAP server is not provided
What it means
LdapServerBeanDefinitionParser.getRootBeanDefinition() selects the embedded container implementation by mode; only UnboundID is supported. If isUnboundIdEnabled(mode) is false (i.e. mode set to a non-UnboundID value like the removed ApacheDS), it throws IllegalStateException because no embedded server implementation is available.
Source
Thrown at config/src/main/java/org/springframework/security/config/ldap/LdapServerBeanDefinitionParser.java:175
}
ldapContainer.getConstructorArgumentValues().addGenericArgumentValue(ldifs);
ldapContainer.getPropertyValues().addPropertyValue("port", getPort(element));
if (parserContext.getRegistry().containsBeanDefinition(BeanIds.EMBEDDED_UNBOUNDID)) {
parserContext.getReaderContext()
.error("Only one embedded server bean is allowed per application context", element);
}
String beanId = resolveBeanId(mode);
if (beanId != null) {
parserContext.getRegistry().registerBeanDefinition(beanId, ldapContainer);
}
return (RootBeanDefinition) contextSource.getBeanDefinition();
}
private RootBeanDefinition getRootBeanDefinition(String mode) {
if (isUnboundIdEnabled(mode)) {
return new RootBeanDefinition(UNBOUNDID_CONTAINER_CLASSNAME, null, null);
}
throw new IllegalStateException("Embedded LDAP server is not provided");
}
private String resolveBeanId(String mode) {
if (isUnboundIdEnabled(mode)) {
return BeanIds.EMBEDDED_UNBOUNDID;
}
return null;
}
private boolean isUnboundIdEnabled(String mode) {
return "unboundid".equals(mode) || unboundIdPresent;
}
private String getPort(Element element) {
String port = element.getAttribute(ATT_PORT);
return (StringUtils.hasText(port) ? port : getDefaultPort());
}
View on GitHub (pinned to 96852e8860)
Solutions
- Remove the mode attribute or set it to the UnboundID mode so the UnboundID container bean definition is used.
- Add the unboundid-ldapsdk dependency and drop legacy ApacheDS references.
- Point <ldap-server/> at an external server (url attribute) instead of embedded mode.
Example fix
// before <security:ldap-server mode="apacheds" ldif="classpath:data.ldif"/> // after <security:ldap-server ldif="classpath:data.ldif"/>
Defensive patterns
Strategy: validation
Validate before calling
String mode = element.getAttribute("mode");
if (mode != null && !mode.isEmpty() && !"unboundid".equals(mode)) {
throw new IllegalArgumentException("Unsupported embedded LDAP mode: " + mode + "; use UnboundID");
} Try / catch
try { parser.parse(element, parserContext); }
catch (IllegalStateException e) {
if (e.getMessage().contains("Embedded LDAP server is not provided")) dropLegacyModeAttribute();
} Prevention
- Remove legacy mode="apacheds" attributes after upgrading to Spring Security 4+
- Use external ldap url for non-UnboundID servers
- Keep namespace schema validation enabled to catch invalid attribute values
When it happens
Trigger: <ldap-server/> with a mode attribute value other than the UnboundID-supported one (e.g. legacy mode="apacheds"), causing isUnboundIdEnabled() to return false during bean definition parsing.
Common situations: Migrating from Spring Security 3.x where ApacheDS embedded mode existed; keeping mode="apacheds" after upgrade; typos in the mode attribute.
Related errors
- Embedded LDAP server is not provided
- managerPassword is required if managerDn is supplied
- Embedded LDAP server is not provided
- No BaseLdapPathContextSource instances found. Have you added
- More than one BaseLdapPathContextSource instance found. Plea
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/7673b9ced5c6e331.
Report an issue: GitHub.