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

  1. 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.
  2. Compare the exact query parameters of the validation request against the chosen validation specification's requirements (renew, gateway, etc.).
  3. 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

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


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)