spring-projects/spring-security · error · UncategorizedLdapException

<namingException.getMessage()>

Error message

<namingException.getMessage()>

What it means

ActiveDirectoryLdapAuthenticationProvider's bindAsUser binds as the authenticating user against Active Directory. If the resulting NamingException is an AuthenticationException or OperationNotSupportedException it is treated as bad credentials; any other NamingException is converted with LdapUtils.convertLdapException(ex) and thrown with the original naming exception's message. This propagates infrastructure-level LDAP failures rather than masking them as login failures.

Source

Thrown at ldap/src/main/java/org/springframework/security/ldap/authentication/ad/ActiveDirectoryLdapAuthenticationProvider.java:223

		// TODO. add DNS lookup based on domain
		Hashtable<String, Object> env = new Hashtable<>();
		env.put(Context.SECURITY_AUTHENTICATION, "simple");
		String bindPrincipal = createBindPrincipal(username);
		env.put(Context.SECURITY_PRINCIPAL, bindPrincipal);
		env.put(Context.PROVIDER_URL, this.url);
		env.put(Context.SECURITY_CREDENTIALS, password);
		env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
		env.put(Context.OBJECT_FACTORIES, DefaultDirObjectFactory.class.getName());
		env.putAll(this.contextEnvironmentProperties);
		try {
			return this.contextFactory.createContext(env);
		}
		catch (NamingException ex) {
			if ((ex instanceof AuthenticationException) || (ex instanceof OperationNotSupportedException)) {
				handleBindException(bindPrincipal, ex);
				throw badCredentials(ex);
			}
			throw LdapUtils.convertLdapException(ex);
		}
	}

	private void handleBindException(String bindPrincipal, NamingException exception) {
		this.logger.debug(LogMessage.format("Authentication for %s failed:%s", bindPrincipal, exception));
		handleResolveObj(exception);
		int subErrorCode = parseSubErrorCode(exception.getMessage());
		if (subErrorCode <= 0) {
			this.logger.debug("Failed to locate AD-specific sub-error code in message");
			return;
		}
		this.logger
			.info(LogMessage.of(() -> "Active Directory authentication failed: " + subCodeToLogMessage(subErrorCode)));
		if (this.convertSubErrorCodesToExceptions) {
			raiseExceptionForErrorCode(subErrorCode, exception);
		}
	}

View on GitHub (pinned to 96852e8860)

Solutions

  1. Verify the AD domain and URL configured in ActiveDirectoryLdapAuthenticationProvider (domain + rootDn/url) resolve and are reachable from the app.
  2. Check the cause chain of the converted exception for the underlying JNDI diagnostic.
  3. If using LDAPS, confirm the DC certificate is trusted by the JVM truststore to avoid SSL handshake NamingExceptions.
  4. Confirm port correctness: 389/636 (or 3268/3269 for GC) and no firewall blocking.

Example fix

// before: wrong URL scheme causing connect NamingException
new ActiveDirectoryLdapAuthenticationProvider("example.com", "ldaps://dc.example.com:389");
// after: port matches scheme
new ActiveDirectoryLdapAuthenticationProvider("example.com", "ldaps://dc.example.com:636");
Defensive patterns

Strategy: try-catch

Validate before calling

// preflight AD connectivity and cert trust
SSLSocketFactory f = (SSLSocketFactory) SSLSocketFactory.getDefault();
try (Socket s = f.createSocket(dcHost, 636)) {
    assert s.isConnected();
} catch (IOException e) {
    fail("AD endpoint unreachable: " + e.getMessage());
}

Try / catch

try {
    provider.authenticate(token);
} catch (org.springframework.security.authentication.InternalAuthenticationServiceException e) {
    Throwable root = ExceptionUtils.getRootCause(e);
    log.error("AD bind infrastructure failure", root); // distinguish from BadCredentialsException
}

Prevention

When it happens

Trigger: Calling authenticate() (via doAuthentication -> bindAsUser) when the AD bind throws a non-authentication NamingException: server unreachable, port 636/389 wrong, DNS resolution failure, or AD refusing the operation for reasons other than bad password.

Common situations: AD domain controller hostname typo or unreachable DC, using wrong port (LDAPS vs LDAP), connectivity/firewall issues in DMZ, or AD returning unexpected errors like unavailable server or time skew (KRB5/NTLM mismatches).

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


AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10). Data as JSON: /api/errors/5f973abbc4d803d0. Report an issue: GitHub.