{"record":{"id":"15c1019c08dc6839","repo":"apereo/cas","slug":"no-authentication-found-for-ticket","errorCode":null,"errorMessage":"No authentication found for ticket ","messagePattern":"No authentication found for ticket ","errorType":"exception","errorClass":"InvalidTicketException","httpStatus":null,"severity":"error","filePath":"support/cas-server-support-actions-core/src/main/java/org/apereo/cas/web/flow/GenerateServiceTicketAction.java","lineNumber":77,"sourceCode":"     * authenticate and verify credentials.\n     * <p>\n     * In subsequent authentication flows where a TGT is available and only an ST needs to be\n     * created, there are no cached copies of the credential, since we do have a TGT available.\n     * So we will grab the available authentication and produce the final result based on that.\n     */\n    @Override\n    protected @Nullable Event doExecuteInternal(final RequestContext context) throws Exception {\n        val service = WebUtils.getService(context);\n        LOGGER.trace(\"Service asking for service ticket is [{}]\", service);\n\n        val ticketGrantingTicket = WebUtils.getTicketGrantingTicketId(context);\n        LOGGER.debug(\"Ticket-granting ticket found in the context is [{}]\", ticketGrantingTicket);\n\n        try {\n            val authentication = ticketRegistrySupport.getAuthenticationFrom(ticketGrantingTicket);\n            if (authentication == null) {\n                val authn = new AuthenticationException(\"No authentication found for ticket \" + ticketGrantingTicket);\n                throw new InvalidTicketException(authn, ticketGrantingTicket);\n            }\n\n            val selectedService = authenticationRequestServiceSelectionStrategies.resolveService(service);\n            val registeredService = servicesManager.findServiceBy(selectedService);\n            LOGGER.debug(\"Registered service asking for service ticket is [{}]\", registeredService);\n            WebUtils.putRegisteredService(context, registeredService);\n            WebUtils.putServiceIntoFlowScope(context, service);\n\n            if (registeredService != null) {\n                val url = registeredService.getAccessStrategy().getUnauthorizedRedirectUrl();\n                if (url != null) {\n                    LOGGER.debug(\"Registered service may redirect to [{}] for unauthorized access requests\", url);\n                }\n                WebUtils.putUnauthorizedRedirectUrlIntoFlowScope(context, url);\n            }\n            if (WebUtils.getWarningCookie(context)) {\n                LOGGER.debug(\"Warning cookie is present in the request context. Routing result to [{}] state\", CasWebflowConstants.STATE_ID_WARN);\n                return result(CasWebflowConstants.STATE_ID_WARN);","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-actions-core/src/main/java/org/apereo/cas/web/flow/GenerateServiceTicketAction.java#L59-L95","documentation":"GenerateServiceTicketAction (webflow action that grants a service ticket from the TGT) fetches the Authentication for the TGT via ticketRegistrySupport. If it returns null, the TGT has no authentication record (expired/evicted/inconsistent ticket state), so it throws InvalidTicketException with AuthenticationException message \"No authentication found for ticket <id>\".","triggerScenarios":"Flow action executed with a TGT id present in context but the authentication object is missing from the ticket registry — e.g. registry eviction/TTL cleanup removed the authn, registry replication lag, or a corrupted TGT entry.","commonSituations":"Distributed ticket registries (Redis/JDBC/Mongo/Hazelcast) with inconsistent or too-aggressive eviction; long-running flows outliving ticket registry timeouts; manual registry cleanup; clock/TTL misconfiguration between nodes.","solutions":["Force the user to re-authenticate: send the flow to the login transition when this error occurs instead of continuing to ST generation","Check ticket registry health/replication (e.g. Redis/Hazelcast cluster consistency) and TTL settings so authn outlives the TGT","Clear stale TGT cookies and restart the login flow","Increase cas.ticket.tgt.time-to-kill-in-seconds / max-time-to-live-in-seconds if flows legitimately run long"],"exampleFix":"// before: assuming authentication always exists\nval authn = ticketRegistrySupport.getAuthenticationFrom(tgtId);\nval selectedService = strategies.resolveService(service);\n// after\nval authn = ticketRegistrySupport.getAuthenticationFrom(tgtId);\nif (authn == null) {\n    return error(context); // transition to login/re-authentication\n}\nval selectedService = strategies.resolveService(service);","handlingStrategy":"validation","validationCode":"Authentication authn = ticketRegistrySupport.getAuthenticationFrom(tgtId);\nif (authn == null) {\n    return transition to login; // TGT is expired, evicted, or inconsistent\n}","typeGuard":"boolean tgtHasAuthentication = ticketRegistrySupport.getAuthenticationFrom(tgtId) != null;","tryCatchPattern":"try {\n    return generateServiceTicketAction.execute(context);\n} catch (InvalidTicketException e) {\n    // route flow to the login transition for re-authentication\n    return error(context);\n}","preventionTips":["Size ticket registry TTLs so authentication outlives the flow","Monitor distributed registry (Redis/Hazelcast/etc.) consistency","Treat null authentication as 're-authenticate', never proceed to ST issuance"],"tags":["service-ticket","ticket-registry","webflow"],"backgroundTag":"entity-not-found","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"}