apereo/cas · warning
Security token ticket
Error message
Security token ticket [{}] is not found or has expired What it means
The WS-Federation IdP controller looks up the security-token ticket (RST/wresult reference prefixed with the SecurityTokenTicket prefix) in the ticket registry; if the ticket is absent or expired the controller returns null and the token cannot be obtained. This is a warn log, not an exception.
Solutions
- Raise the security token ticket expiration (cas.authn.wsfed-idp ticket time-to-kill) to cover your flow length
- Ensure all CAS nodes share the same ticket registry backend
- Have the user restart the sign-in flow instead of replaying stale URLs
- Enable ticket-registry logging to check whether the ticket was evicted or expired
Example fix
// before (default short TTL) cas.authn.wsfed-idp.security-token-tickets.time-to-kill-in-seconds=60 // after cas.authn.wsfed-idp.security-token-tickets.time-to-kill-in-seconds=600
Defensive patterns
Strategy: retry
Try / catch
if (token == null) { /* restart the WS-Federation flow to obtain a fresh ticket */ } Prevention
- Set security-token-ticket TTL larger than the expected flow duration
- Share one ticket registry across all CAS nodes
- Avoid bookmarking/replaying federation callback URLs
When it happens
Trigger: getSecurityTokenFromRequest() extracts a wctx/ticket id starting with SecurityTokenTicket.PREFIX, calls ticketRegistry.getTicket(sts, SecurityTokenTicket.class), and gets null or an expired ticket.
Common situations: Long-running browser flow exceeded the security-token-ticket expiration time; ticket registry (e.g. clustered Redis/Memcached) lost the ticket or nodes point at different stores; user replayed an old bookmarked URL; ticket cleanup ran between request steps.
Related errors
- No authentication found for ticket
- Invalid token:
- Invalid token:
- InvalidTicketException
- Failed to authenticate code
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/6ec1b648963b1e00.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-ws-idp/src/main/java/org/apereo/cas/ws/idp/web/BaseWSFederationRequestController.java:85
/**
* Gets security token from request.
*
* @param request the request
* @return the security token from request
*/
protected SecurityToken getSecurityTokenFromRequest(final HttpServletRequest request) {
val cookieValue = configContext.getTicketGrantingTicketCookieGenerator().retrieveCookieValue(request);
if (StringUtils.isNotBlank(cookieValue)) {
val tgt = configContext.getTicketRegistry().getTicket(cookieValue, TicketGrantingTicket.class);
if (tgt != null) {
val sts = tgt.getDescendantTickets().stream()
.filter(t -> t.startsWith(SecurityTokenTicket.PREFIX))
.findFirst()
.orElse(null);
if (StringUtils.isNotBlank(sts)) {
val stt = configContext.getTicketRegistry().getTicket(sts, SecurityTokenTicket.class);
if (stt == null || stt.isExpired()) {
LOGGER.warn("Security token ticket [{}] is not found or has expired", sts);
return null;
}
if (stt.getSecurityToken() == null || stt.getSecurityToken().isExpired()) {
LOGGER.warn("Security token linked to ticket [{}] has expired", sts);
return null;
}
return stt.getSecurityToken();
}
}
}
return null;
}
protected boolean shouldRenewAuthentication(final WSFederationRequest fedRequest,
final HttpServletRequest request) {
if (StringUtils.isBlank(fedRequest.wfresh()) || !NumberUtils.isCreatable(fedRequest.wfresh())) {
return false;View on GitHub (pinned to e7288fc434)