{"record":{"id":"433145e156c8ffb8","repo":"apereo/cas","slug":"cannot-get-connection-from-pool-to-validate-spnego","errorCode":null,"errorMessage":"Cannot get connection from pool to validate SPNEGO Token","messagePattern":"Cannot get connection from pool to validate SPNEGO Token","errorType":"exception","errorClass":"FailedLoginException","httpStatus":null,"severity":"error","filePath":"support/cas-server-support-spnego/src/main/java/org/apereo/cas/support/spnego/authentication/handler/support/JcifsSpnegoAuthenticationHandler.java","lineNumber":66,"sourceCode":"    protected AuthenticationHandlerExecutionResult doAuthentication(final Credential credential, final Service service) throws Throwable {\n        val spnegoCredential = (SpnegoCredential) credential;\n        if (!spnegoProperties.isNtlmAllowed() && spnegoCredential.isNtlm()) {\n            throw new FailedLoginException(\"NTLM not allowed\");\n        }\n\n        try {\n            LOGGER.debug(\"Waiting for connection to validate SPNEGO Token\");\n            val poolTimeoutInMilliseconds = Beans.newDuration(spnegoProperties.getPoolTimeout()).toMillis();\n            val authentications = authenticationsPool.poll(poolTimeoutInMilliseconds, TimeUnit.MILLISECONDS);\n            if (authentications != null) {\n                try {\n                    return doInternalAuthentication(authentications, spnegoCredential, service);\n                } finally {\n                    authenticationsPool.add(authentications);\n                    LOGGER.debug(\"Returned connection to pool\");\n                }\n            }\n            throw new FailedLoginException(\"Cannot get connection from pool to validate SPNEGO Token\");\n        } catch (final InterruptedException e) {\n            throw new FailedLoginException(\"Thread interrupted while waiting for connection to validate SPNEGO Token\");\n        }\n    }\n\n    protected AuthenticationHandlerExecutionResult doInternalAuthentication(final List<Authentication> authentications,\n                                                                            final SpnegoCredential spnegoCredential, final Service service) throws Throwable {\n        var principal = (java.security.Principal) null;\n        var nextToken = (byte[]) null;\n        val it = authentications.iterator();\n        while (nextToken == null && it.hasNext()) {\n            try {\n                val authentication = it.next();\n                authentication.reset();\n                LOGGER.debug(\"Processing SPNEGO authentication\");\n                authentication.process(spnegoCredential.getInitToken());\n                principal = authentication.getPrincipal();\n                LOGGER.debug(\"Authenticated SPNEGO principal [{}]. Retrieving the next token for authentication...\",","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-spnego/src/main/java/org/apereo/cas/support/spnego/authentication/handler/support/JcifsSpnegoAuthenticationHandler.java#L48-L84","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\ncas.authn.spnego.pool-timeout=PT0.5S\n// after\ncas.authn.spnego.pool-timeout=PT10S","handlingStrategy":"retry","validationCode":"// size check: pool size >= expected concurrent SPNEGO logins\npoolSize >= peakLoginsPerSecond * avgAcquireMillis / 1000","typeGuard":null,"tryCatchPattern":"try {\n    return handler.authenticate(credential);\n} catch (FailedLoginException e) {\n    if (e.getMessage().contains(\"connection from pool\")) {\n        // brief backoff then retry once\n        Thread.sleep(100);\n        return handler.authenticate(credential);\n    }\n    throw e;\n}","preventionTips":["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"],"tags":["spnego","pool","timeout","authentication"],"backgroundTag":"request-timeout","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"}