spring-projects/spring-security · error · IllegalStateException

managerPassword is required if managerDn is supplied

Error message

managerPassword is required if managerDn is supplied

What it means

LdapAuthenticationProviderConfigurer.build() creates a DefaultSpringSecurityContextSource and, if a managerDn (bind user DN) was configured, requires a matching managerPassword; otherwise it throws IllegalStateException. The manager credentials are mandatory because the context source must bind to the LDAP server for searches.

Solutions

  1. Call .managerPassword("...") alongside .managerDn("...") in the LdapAuthenticationProviderConfigurer.
  2. Provide the password from configuration/environment, e.g. .managerPassword(env.getProperty("LDAP_PASSWORD")), ensuring the property exists.
  3. If anonymous binding is acceptable, remove the managerDn entirely so no password is required.
  4. Double-check property key spelling/binding in application.yml so managerPassword is actually populated.

Example fix

// before
auth.ldapAuthentication().userDnPatterns("uid={0},ou=people").managerDn("cn=admin,dc=example,dc=com");
// after
auth.ldapAuthentication().userDnPatterns("uid={0},ou=people")
    .managerDn("cn=admin,dc=example,dc=com")
    .managerPassword(env.getProperty("LDAP_MANAGER_PASSWORD"));
Defensive patterns

Strategy: validation

Validate before calling

// before building the configurer
if (managerDn != null && (managerPassword == null || managerPassword.isBlank())) {
    throw new IllegalArgumentException("managerPassword must accompany managerDn");
}

Try / catch

try {
    return auth.ldapAuthentication()...build();
} catch (IllegalStateException e) {
    if (e.getMessage().contains("managerPassword")) {
        throw new ConfigurationException("Set LDAP managerDn AND managerPassword (e.g. via env var)", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Configuring .managerDn("cn=admin,dc=example,dc=com") via .managerDn() (or managerDn property) without calling .managerPassword(...), then completing the LDAP configuration (build/startup).

Common situations: Copy-pasted LDAP config where the password was left as a placeholder or loaded from an env var that resolves to null; YAML/properties wiring where managerPassword key is misspelled; switching from anonymous-bind config to a manager DN without adding the password.

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 spring-projects/spring-security@96852e8860 (2026-09-10). Data as JSON: /api/errors/640afe4cf99acb1a. Report an issue: GitHub.

Appendix: source

Thrown at config/src/main/java/org/springframework/security/config/annotation/authentication/configurers/ldap/LdapAuthenticationProviderConfigurer.java:567

		/**
		 * Gets the {@link LdapAuthenticationProviderConfigurer} for further
		 * customizations.
		 * @return the {@link LdapAuthenticationProviderConfigurer} for further
		 * customizations
		 */
		public LdapAuthenticationProviderConfigurer<B> and() {
			return LdapAuthenticationProviderConfigurer.this;
		}

		private DefaultSpringSecurityContextSource build() {
			if (this.url == null) {
				startEmbeddedLdapServer();
			}
			DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource(getProviderUrl());
			if (this.managerDn != null) {
				contextSource.setUserDn(this.managerDn);
				if (this.managerPassword == null) {
					throw new IllegalStateException("managerPassword is required if managerDn is supplied");
				}
				contextSource.setPassword(this.managerPassword);
			}
			contextSource = postProcess(contextSource);
			return contextSource;
		}

		private void startEmbeddedLdapServer() {
			if (unboundIdPresent) {
				UnboundIdContainer unboundIdContainer = new UnboundIdContainer(this.root, this.ldif);
				unboundIdContainer.setPort(getPort());
				postProcess(unboundIdContainer);
				this.port = unboundIdContainer.getPort();
			}
			else {
				throw new IllegalStateException("Embedded LDAP server is not provided");
			}
		}

View on GitHub (pinned to 96852e8860)