{"record":{"id":"430f26781edc2ec4","repo":"apereo/cas","slug":"thread-interrupted-while-waiting-for-connection-to","errorCode":null,"errorMessage":"Thread interrupted while waiting for connection to validate SPNEGO Token","messagePattern":"Thread interrupted while waiting for connection to validate SPNEGO Token","errorType":"exception","errorClass":"FailedLoginException","httpStatus":null,"severity":"warning","filePath":"support/cas-server-support-spnego/src/main/java/org/apereo/cas/support/spnego/authentication/handler/support/JcifsSpnegoAuthenticationHandler.java","lineNumber":68,"sourceCode":"        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...\",\n                    Optional.ofNullable(principal).map(java.security.Principal::getName).orElse(null));\n                nextToken = authentication.getNextToken();","sourceCodeStart":50,"sourceCodeEnd":86,"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#L50-L86","documentation":"While waiting to borrow a connection from the SPNEGO authentications pool, the calling thread received InterruptedException; the handler converts this into FailedLoginException. It indicates the thread was interrupted during pool.poll(), typically during server shutdown or executor termination.","triggerScenarios":"CAS shutdown/redeployment while SPNEGO logins are in flight; the request thread's executor is shutting down; manual thread interruption (e.g. request timeout killer) hitting a thread blocked in poll().","commonSituations":"Graceful shutdown under load; container orchestrator terminating pods; long-running blocked threads interrupted by timeouts.","solutions":["Retry the authentication once the server is stable; this is usually transient during shutdown.","Ensure clean shutdown ordering so login requests complete before pool/executor teardown.","Check for overly aggressive request-timeout or thread-interruption policies in the servlet container/proxy.","Investigate thread leaks that keep threads blocked in the pool and force interrupt-based cleanup."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    return handler.authenticate(credential);\n} catch (FailedLoginException e) {\n    if (e.getMessage().contains(\"Thread interrupted\")) {\n        LOGGER.warn(\"SPNEGO auth interrupted; retry after shutdown/deploy completes\");\n    }\n    throw e;\n}","preventionTips":["Avoid deploying during login-heavy windows","Verify shutdown hooks drain in-flight requests before closing pools","Check proxy/servlet-container timeout settings that interrupt worker threads"],"tags":["spnego","interrupted","threading","pool"],"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"}