{"record":{"id":"874b863a02d58f9e","repo":"apereo/cas","slug":"attribute-query-ticket-has-either-expired-or","errorCode":null,"errorMessage":"Attribute query ticket [{}] has either expired, or it is linked to a single sign-on session that is no longer valid and has now expired","messagePattern":"Attribute query ticket \\[(.+?)\\] has either expired, or it is linked to a single sign-on session that is no longer valid and has now expired","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"support/cas-server-support-saml-idp-web/src/main/java/org/apereo/cas/support/saml/web/idp/profile/query/SamlIdPSaml2AttributeQueryProfileHandlerController.java","lineNumber":82,"sourceCode":"        }\n\n        val ctx = decodeSoapRequest(request);\n        val query = (AttributeQuery) ctx.getMessage();\n        try {\n            val issuer = Objects.requireNonNull(query).getIssuer().getValue();\n            val registeredService = verifySamlRegisteredService(issuer, request);\n            val adaptor = getSamlMetadataFacadeFor(registeredService, query);\n            val facade = adaptor.orElseThrow(() -> UnauthorizedServiceException.denied(\"Cannot find metadata linked to %s\".formatted(issuer)));\n            verifyAuthenticationContextSignature(ctx, request, query, facade, registeredService);\n\n            val nameIdValue = determineNameIdForQuery(query, registeredService, facade);\n            val factory = (SamlAttributeQueryTicketFactory) getConfigurationContext().getTicketFactory()\n                .get(SamlAttributeQueryTicket.class);\n            val id = factory.createTicketIdFor(nameIdValue, facade.getEntityId());\n            LOGGER.debug(\"Created ticket id for attribute query [{}]\", id);\n            val ticket = getConfigurationContext().getTicketRegistry().getTicket(id, SamlAttributeQueryTicket.class);\n            if (ticket == null || ticket.isExpired()) {\n                LOGGER.warn(\"Attribute query ticket [{}] has either expired, or it is linked to \"\n                            + \"a single sign-on session that is no longer valid and has now expired\", id);\n                throw new InvalidTicketException(id);\n            }\n            val authentication = ticket.getAuthentication();\n\n            val principal = resolvePrincipalForAttributeQuery(authentication, registeredService);\n            val releasePolicyContext = RegisteredServiceAttributeReleasePolicyContext.builder()\n                .registeredService(registeredService)\n                .applicationContext(getConfigurationContext().getOpenSamlConfigBean().getApplicationContext())\n                .service(ticket.getService())\n                .principal(principal)\n                .build();\n\n            val principalAttributes = registeredService.getAttributeReleasePolicy().getConsentableAttributes(releasePolicyContext);\n            LOGGER.debug(\"Initial consentable principal attributes are [{}]\", principalAttributes);\n\n            val authenticationAttributes = getConfigurationContext().getAuthenticationAttributeReleasePolicy()\n                .getAuthenticationAttributesForRelease(authentication, null, Map.of(), registeredService);","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-saml-idp-web/src/main/java/org/apereo/cas/support/saml/web/idp/profile/query/SamlIdPSaml2AttributeQueryProfileHandlerController.java#L64-L100","documentation":"This warning is logged when a SAML 2.0 Attribute Query request references an attribute query ticket that is absent from the ticket registry or has expired (a query ticket is also expired when its linked SSO session expires). The controller then throws InvalidTicketException and the Attribute Query profile request fails.","triggerScenarios":"A SAML SP sends an AttributeQuery whose NameID and entity ID hash to a SamlAttributeQueryTicket id, but the ticket was already consumed/expired via TTL/TGT-SSO expiry, ticket registry was flushed/evicted, or the SP sends a stale/cached query.","commonSituations":"Ticket registry cleaned by a shared cache (Redis/Hazelcast/Memcached) eviction policy; attribute queries sent long after SSO login; clock skew or aggressive SamlAttributeQueryTicket TTLs; SP caches ticket ids across restarts; clustering with a registry not shared between CAS nodes.","solutions":["Verify SP attribute query timing is within the SamlAttributeQueryTicket TTL and the SSO session is still alive (check cas.authn.saml-idp.core attribute-query ticket expiration settings).","Inspect the ticket registry (cas-management/actuator endpoints or registry backend) to confirm the ticket exists and has not been evicted.","Ensure all CAS nodes share the same ticket registry when running a cluster.","Increase cas.authn.saml-idp.ticket.attribute-query.time-to-kill-in-seconds and underlying SSO/TGT expiration if queries legitimately arrive late.","Debug the id derivation: same NameID value and SP entity id must be used; confirm the SP is not resending modified NameIDs."],"exampleFix":"// before (cas.properties)\ncas.authn.saml-idp.ticket.attribute-query.time-to-kill-in-seconds=30\n// after\ncas.authn.saml-idp.ticket.attribute-query.time-to-kill-in-seconds=300","handlingStrategy":"validation","validationCode":"var ticket = ticketRegistry.getTicket(id, SamlAttributeQueryTicket.class);\nif (ticket == null || ticket.isExpired()) {\n    throw new InvalidTicketException(id);\n}","typeGuard":null,"tryCatchPattern":"try {\n    attributeQueryService.handleQuery(request);\n} catch (InvalidTicketException e) {\n    LOGGER.warn(\"Attribute query ticket expired: {}\", e.getMessage());\n    // respond with SAML error status\n}","preventionTips":["Keep SP attribute query timing well within the ticket TTL and SSO session lifetime.","Use a shared, persistent ticket registry in clustered deployments.","Monitor ticket registry eviction rates.","Alert on frequent InvalidTicketException from the attribute query endpoint."],"tags":["saml","ticket-expired","attribute-query"],"backgroundTag":"jwt-token-expired","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"}