apereo/cas · error · FailedLoginException
Cannot get connection from pool to validate SPNEGO Token
Error message
Cannot get connection from pool to validate SPNEGO Token
What it means
The handler borrows a JCIFS 'authentications' object from an internal connection pool with cas.authn.spnego.pool-timeout as the wait limit. If poll() returns null (pool exhausted / no connection available within the timeout), authentication fails with this FailedLoginException.
Solutions
- Increase cas.authn.spnego.pool-timeout (e.g. to a few seconds) so the handler waits longer for a free connection.
- Increase the JCIFS pool size (jcifs.smb.pool related properties / pool configuration in SpnegoConfiguration) to match peak concurrency.
- Investigate why connections are held long: check KDC/Domain Controller latency.
- Add monitoring/retries around SPNEGO login spikes; scale CAS instances horizontally.
Example fix
// before cas.authn.spnego.pool-timeout=PT0.5S // after cas.authn.spnego.pool-timeout=PT10S
Defensive patterns
Strategy: retry
Validate before calling
// size check: pool size >= expected concurrent SPNEGO logins poolSize >= peakLoginsPerSecond * avgAcquireMillis / 1000
Try / catch
try {
return handler.authenticate(credential);
} catch (FailedLoginException e) {
if (e.getMessage().contains("connection from pool")) {
// brief backoff then retry once
Thread.sleep(100);
return handler.authenticate(credential);
}
throw e;
} Prevention
- Size the authentications pool above peak concurrency
- Set pool-timeout to seconds, not milliseconds
- Monitor KDC/DC latency
- Load-test SPNEGO logins before mass events
When it happens
Trigger: Concurrent SPNEGO authentications exceed the pool capacity (jcifs maxPoolSize/pool settings), or every pooled connection is busy, so pool.poll(poolTimeout) times out and returns null.
Common situations: Login bursts during mass events (start-of-day); pool size configured too small; slow KDC causing pooled connections to be held long; pool-timeout set to a few milliseconds.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
Related errors
- NTLM not allowed
- Thread interrupted while waiting for connection to validate…
- Principal is null, the processing of the SPNEGO Token failed
- Authentication handler is disabled
- No user can be accepted because none is defined
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/433145e156c8ffb8.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-spnego/src/main/java/org/apereo/cas/support/spnego/authentication/handler/support/JcifsSpnegoAuthenticationHandler.java:66
protected AuthenticationHandlerExecutionResult doAuthentication(final Credential credential, final Service service) throws Throwable {
val spnegoCredential = (SpnegoCredential) credential;
if (!spnegoProperties.isNtlmAllowed() && spnegoCredential.isNtlm()) {
throw new FailedLoginException("NTLM not allowed");
}
try {
LOGGER.debug("Waiting for connection to validate SPNEGO Token");
val poolTimeoutInMilliseconds = Beans.newDuration(spnegoProperties.getPoolTimeout()).toMillis();
val authentications = authenticationsPool.poll(poolTimeoutInMilliseconds, TimeUnit.MILLISECONDS);
if (authentications != null) {
try {
return doInternalAuthentication(authentications, spnegoCredential, service);
} finally {
authenticationsPool.add(authentications);
LOGGER.debug("Returned connection to pool");
}
}
throw new FailedLoginException("Cannot get connection from pool to validate SPNEGO Token");
} catch (final InterruptedException e) {
throw new FailedLoginException("Thread interrupted while waiting for connection to validate SPNEGO Token");
}
}
protected AuthenticationHandlerExecutionResult doInternalAuthentication(final List<Authentication> authentications,
final SpnegoCredential spnegoCredential, final Service service) throws Throwable {
var principal = (java.security.Principal) null;
var nextToken = (byte[]) null;
val it = authentications.iterator();
while (nextToken == null && it.hasNext()) {
try {
val authentication = it.next();
authentication.reset();
LOGGER.debug("Processing SPNEGO authentication");
authentication.process(spnegoCredential.getInitToken());
principal = authentication.getPrincipal();
LOGGER.debug("Authenticated SPNEGO principal [{}]. Retrieving the next token for authentication...",View on GitHub (pinned to e7288fc434)