spring-projects/spring-security · critical · InternalAuthenticationServiceException

Connection to LDAP server failed.

Error message

Connection to LDAP server failed.

What it means

ActiveDirectoryLdapAuthenticationProvider.searchForUser translates a Spring LDAP CommunicationException into 'Connection to LDAP server failed.' via badLdapConnection. It means the provider could not establish or maintain a network connection to the Active Directory domain controller while executing the user search, so authentication could not proceed. This is an infrastructure/connectivity failure, not a credentials problem.

Source

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

		SingleContextSource contextSource = new SingleContextSource(context);
		LdapClient ldapClient = LdapClient.builder()
			.contextSource(contextSource)
			.defaultSearchControls(() -> searchControls)
			.ignorePartialResultException(true)
			.build();
		try {
			LdapQuery query = LdapQueryBuilder.query()
				.base(searchRoot)
				.searchScope(SearchScope.SUBTREE)
				.filter(this.searchFilter, bindPrincipal, username);
			DirContextOperations result = ldapClient.search().query(query).toEntry();
			if (result == null) {
				throw new IncorrectResultSizeDataAccessException(1, 0);
			}
			return result;
		}
		catch (CommunicationException ex) {
			throw badLdapConnection(ex);
		}
		catch (IncorrectResultSizeDataAccessException ex) {
			// Search should never return multiple results if properly configured -
			if (ex.getActualSize() != 0) {
				throw ex;
			}
			// If we found no results, then the username/password did not match
			UsernameNotFoundException userNameNotFoundException = UsernameNotFoundException.fromUsername(username, ex);
			throw badCredentials(userNameNotFoundException);
		}
		catch (org.springframework.ldap.NamingException ex) {
			if (ex.getCause() instanceof NamingException original) {
				throw original;
			}
			throw badCredentials(ex);
		}
	}

View on GitHub (pinned to 96852e8860)

Solutions

  1. Verify network reachability of the domain controller: run `nc -zv ad.example.com 636` (or 389) from the application host.
  2. Check the configured domain/rootDn: new ActiveDirectoryLdapAuthenticationProvider(domain, url) — confirm the domain resolves via DNS and the URL uses the correct scheme (ldaps:// for TLS).
  3. If using ldaps://, import the AD certificate into the JVM trust store: keytool -importcert -alias ad -file ad.cer -keystore $JAVA_HOME/lib/security/cacerts.
  4. Ensure the ActiveDirectoryLdapAuthenticationProvider bean is a singleton shared across requests; creating it per-request can exhaust connections.
  5. Review the full CommunicationException stack trace for nested causes (UnknownHostException, SSLHandshakeException, SocketTimeoutException) and fix the specific root cause.

Example fix

// before
ActiveDirectoryLdapAuthenticationProvider provider =
    new ActiveDirectoryLdapAuthenticationProvider("corp.example.com", "ldap://wrong-host:389");
// after
ActiveDirectoryLdapAuthenticationProvider provider =
    new ActiveDirectoryLdapAuthenticationProvider("corp.example.com", "ldaps://dc1.corp.example.com:636");
Defensive patterns

Strategy: try-catch

Validate before calling

boolean ldapReachable;
try (Socket s = new Socket()) {
    s.connect(new InetSocketAddress("dc1.corp.example.com", 636), 3000);
    ldapReachable = true;
} catch (IOException e) {
    ldapReachable = false;
}

Try / catch

try {
    authenticationManager.authenticate(token);
} catch (CommunicationException | BadCredentialsException e) {
    if (e.getCause() instanceof ConnectException || e instanceof CommunicationException) {
        // infrastructure problem: alert ops / retry with backoff
    } else {
        // real bad credentials: return 401
    }
}

Prevention

When it happens

Trigger: Calling authenticate(username, password) on ActiveDirectoryLdapAuthenticationProvider when the underlying LDAP search throws org.springframework.ldap.CommunicationException — e.g. the AD server is unreachable, DNS for the domain fails, the connection was dropped mid-search, or the port is blocked.

Common situations: Wrong or unresolvable AD domain/URL configuration; firewall or security group blocking port 389/636; domain controller down or TLS (ldaps://) handshake failing; DNS issues in containers/K8s; missing Java trust store entries for the LDAPS certificate.

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/1cd32198b2ae5015. Report an issue: GitHub.