apereo/cas · warning
Service ticket [ ] does not satisfy validation…
Error message
Service ticket [{}] does not satisfy validation specification. What it means
validateAssertion binds each configured validation specification (e.g. Cas20WithoutProxyingValidationSpecification) to the HTTP request and checks isSatisfiedBy; when the assertion fails the spec's rules (most commonly renew=true being violated), the controller logs this warning and returns validation failure. The ticket itself may be valid but the request parameters don't satisfy the requested validation semantics.
Solutions
- Remove renew=true from the validation call, or force a fresh login (renew=true on the login request) when the ticket is issued so the assertion satisfies the spec.
- Compare the exact query parameters of the validation request against the chosen validation specification's requirements (renew, gateway, etc.).
- If a custom specification is configured, fix or relax its isSatisfiedBy logic to match your intended validation semantics.
Example fix
// before GET /p3/serviceValidate?service=https://app&ticket=ST-1&renew=true // after (either drop renew on validation, or issue ticket with renew=true at login) GET /p3/serviceValidate?service=https://app&ticket=ST-1
Defensive patterns
Strategy: validation
Validate before calling
// client side: only send renew=true if the login that produced the ticket also used renew=true
if (validateWithRenew && !ticketIssuedWithRenew) {
throw new Error('renew=true validation requires the ticket to be issued with renew=true');
} Prevention
- Match renew semantics between the login request and the validation request.
- Do not blindly copy validation URLs with renew=true from other integrations.
- If you add custom ValidationSpecifications, document their required request parameters.
When it happens
Trigger: validateAssertion (called by handleTicketValidation after successful ticket retrieval) iterates serviceValidateConfigurationContext.getValidationSpecifications(); spec.isSatisfiedBy(assertion, request) returns false — typically because the client passed renew=true but the ticket was granted without a fresh primary authentication, or check-valid-only semantics mismatch.
Common situations: Client sends renew=true on validation while the CAS login that produced the ticket didn't force re-authentication; custom ValidationSpecification added via configuration rejects otherwise-valid assertions; stale client code sending parameters the spec interprets strictly.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Service [ ] is not found in service registry.
- INVALID_REQUEST
- INVALID_PROXY_CALLBACK
- ServiceManagement: Unauthorized Service Access. Service
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/9f909aef3ac12a41.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-validation-core/src/main/java/org/apereo/cas/web/AbstractServiceValidateController.java:256
}
protected Map<String, ?> augmentSuccessViewModelObjects(final Assertion assertion) {
return new HashMap<>();
}
private String handleProxyIouDelivery(final Credential serviceCredential, final Ticket proxyGrantingTicket) throws Throwable {
return serviceValidateConfigurationContext.getProxyHandler().handle(serviceCredential, proxyGrantingTicket);
}
private boolean validateAssertion(final HttpServletRequest request, final String serviceTicketId,
final Assertion assertion, final Service service) {
for (val spec : serviceValidateConfigurationContext.getValidationSpecifications()) {
spec.reset();
val binder = new ServletRequestDataBinder(spec, "validationSpecification");
initBinder(request, binder);
binder.bind(request);
if (!spec.isSatisfiedBy(assertion, request)) {
LOGGER.warn("Service ticket [{}] does not satisfy validation specification.", serviceTicketId);
return false;
}
}
enforceTicketValidationAuthorizationFor(request, service, assertion);
return true;
}
private ModelAndView generateErrorView(final String code,
final String description,
final HttpServletRequest request,
final WebApplicationService service) {
val clientInfo = ClientInfoHolder.getClientInfo();
val event = new CasServiceTicketValidationFailedEvent(this, code, description, service, clientInfo);
getServiceValidateConfigurationContext().getApplicationContext().publishEvent(event);
val modelAndView = serviceValidateConfigurationContext.getValidationViewFactory()
.getModelAndView(request, false, service, getClass());
modelAndView.addObject(CasViewConstants.MODEL_ATTRIBUTE_NAME_ERROR_CODE, StringEscapeUtils.escapeHtml4(code));View on GitHub (pinned to e7288fc434)