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
- Verify network reachability of the domain controller: run `nc -zv ad.example.com 636` (or 389) from the application host.
- 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).
- 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.
- Ensure the ActiveDirectoryLdapAuthenticationProvider bean is a singleton shared across requests; creating it per-request can exhaust connections.
- 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
- Add a startup health check that binds to the AD server before accepting traffic.
- Use ldaps:// with certificates imported into the JVM trust store.
- Reuse a singleton provider bean; configure connection pooling in the embedded context source.
- Monitor DNS resolution and DC availability from the app subnet.
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
- <namingException.getMessage()>
- <namingException.getMessage()>
- Bad credentials
- Failed to obtain DirContext
- Empty Username
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/1cd32198b2ae5015.
Report an issue: GitHub.