{"record":{"id":"675bcbe59698e381","repo":"apereo/cas","slug":"unexpected-ldap-error","errorCode":null,"errorMessage":"Unexpected LDAP error","messagePattern":"Unexpected LDAP error","errorType":"exception","errorClass":"InsufficientAuthenticationException","httpStatus":null,"severity":"error","filePath":"support/cas-server-support-ldap-core/src/main/java/org/apereo/cas/authorization/EndpointLdapAuthenticationProvider.java","lineNumber":110,"sourceCode":"                val entry = response.getLdapEntry();\n                val attributes = new HashMap<String, List<Object>>();\n                entry.getAttributes().forEach(attribute -> attributes.put(attribute.getName(), new ArrayList<>(attribute.getStringValues())));\n                val principal = PrincipalFactoryUtils.newPrincipalFactory().createPrincipal(username, attributes);\n                val authZGen = buildAuthorizationGenerator();\n                val authorities = authZGen.apply(Objects.requireNonNull(principal));\n\n                LOGGER.debug(\"List of authorities remapped from profile roles are [{}]\", authorities);\n                if (authorities.stream().anyMatch(authority -> requiredRoles.contains(authority.getAuthority()))) {\n                    return generateAuthenticationToken(authentication, authorities);\n                }\n                LOGGER.warn(\"User [{}] is not authorized to access the requested resource\", username);\n            } else {\n                LOGGER.warn(\"LDAP authentication response produced no results for [{}]\", username);\n            }\n\n        } catch (final Throwable e) {\n            LoggingUtils.error(LOGGER, e);\n            throw new InsufficientAuthenticationException(\"Unexpected LDAP error\", e);\n        }\n        throw new BadCredentialsException(\"Could not authenticate provided credentials\");\n    }\n\n    @Override\n    public boolean supports(final Class<?> aClass) {\n        return UsernamePasswordAuthenticationToken.class.isAssignableFrom(aClass);\n    }\n\n    private Function<Principal, List<SimpleGrantedAuthority>> buildAuthorizationGenerator() {\n        val properties = ldapProperties.getLdapAuthz();\n\n        if (isGroupBasedAuthorization()) {\n            LOGGER.debug(\"Handling LDAP authorization based on groups\");\n            return new LdapUserGroupsToRolesAuthorizationGenerator(\n                ldapAuthorizationGeneratorUserSearchOperation(),\n                properties.isAllowMultipleResults(),\n                properties.getGroupAttribute(),","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-ldap-core/src/main/java/org/apereo/cas/authorization/EndpointLdapAuthenticationProvider.java#L92-L128","documentation":"EndpointLdapAuthenticationProvider.authenticate() wraps any Throwable raised during LDAP authentication into InsufficientAuthenticationException(\"Unexpected LDAP error\", cause) after logging it. It is a catch-all signaling the LDAP operation itself blew up (connection failure, timeout, communication error), as distinct from bad credentials.","triggerScenarios":"authenticator.authenticate(request) throws — unreachable LDAP host/port, TLS handshake failure, connection-pool timeout, DNS failure, or any runtime exception inside the ldaptive stack.","commonSituations":"Wrong ldapUrl/port; firewall blocks the connection; certificate not trusted (StartTLS/LDAPS); directory temporarily down; connection pool exhausted under load.","solutions":["Read the logged cause (LoggingUtils.error) — it names the real connection/TLS problem","Verify cas.authn.ldap[x].ldap-url, port, and that the server is reachable (ldapsearch/openssl s_client)","Check StartTLS and trust-store settings (validate-on-tls, keystore config)","Review connection pool sizing/timeouts (min/max pool size, block wait time)","Restore directory availability / network path"],"exampleFix":"// before\n// ldap-url=ldap://directory.example.org:10389\n// after (correct host/port + pool tuning)\n// ldap-url=ldaps://directory.example.org:636\n// connection-strategy=ACTIVE_PASSIVE\n// pool.max-size=20","handlingStrategy":"try-catch","validationCode":"// connectivity precheck before authenticate\ntry (Connection c = DefaultConnectionFactory connections.newConnection(props)) {\n    c.open(); // throws if host/port/TLS unreachable\n}","typeGuard":null,"tryCatchPattern":"try {\n    provider.authenticate(token);\n} catch (InsufficientAuthenticationException e) {\n    logger.error(\"LDAP infrastructure error: {}\", e.getCause(), e); // inspect cause for connection/TLS detail\n    throw new ServiceUnavailableException(\"Directory temporarily unavailable\");\n}","preventionTips":["Check ldap-url reachability and DNS before startup","Trust the directory's TLS certificate (trust store / StartTLS config)","Size the connection pool and set sane block-wait/timeout values","Monitor directory availability and alert before users hit the endpoint"],"tags":["ldap","network","connection"],"backgroundTag":"ldap-connection-failed","analyzedSha":"e7288fc434b4f4505b8452e1a57e8fb3111bb863","analyzedAt":"2026-09-08T15:39:16.015Z","contentChangedAt":"2026-09-08T15:39:16.015Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}