apereo/cas · warning

No ticket definition could be found in the catalog to match

Error message

No ticket definition could be found in the catalog to match [{}]

What it means

DynamoDbTicketRegistryFacilitator.get() looks up a TicketDefinition in the ticket catalog by the ticket's prefix before deserializing the item returned by DynamoDB. If no registered ticket definition matches the ticket id's prefix, the item is discarded, a warning is logged, and null is returned instead of a ticket. This guards against materializing ticket types CAS does not know how to handle.

Solutions

  1. Verify the ticket id is well-formed and its prefix matches a known ticket type (TGT-, ST-, PGT-, etc.).
  2. Ensure the TicketCatalog is initialized with a TicketDefinition for that prefix (check TicketCatalogConfigurer beans / cas.ticket.* configuration).
  3. Confirm the module that defines the ticket type (e.g. core-tickets, support-oauth) is on the classpath of the running webapp.
  4. Inspect the DynamoDB item to confirm the id column was not corrupted or written by another application.

Example fix

// before: looking up with a guessed/foreign id
cas.getTicketRegistry().getTicket("UNKNOWN-1234");
// after: guard on catalog membership first
val catalog = cas.getTicketCatalog();
if (catalog.findTicketDefinition("UNKNOWN-1234").isEmpty()) {
    throw new IllegalArgumentException("Unknown ticket id prefix");
}
val ticket = cas.getTicketRegistry().getTicket("UNKNOWN-1234");
Defensive patterns

Strategy: validation

Validate before calling

val definition = ticketCatalog.findTicketDefinition(ticketId);
if (definition.isEmpty()) {
    throw new IllegalArgumentException("No ticket definition for id: " + ticketId);
}
var ticket = ticketRegistry.getTicket(ticketId);

Type guard

boolean isKnownTicket(String ticketId) {
    return ticketId != null && ticketId.contains("-")
        && ticketCatalog.findTicketDefinition(ticketId).isPresent();
}

Prevention

When it happens

Trigger: Calling ticketRegistry.getTicket(ticketId) (which routes to DynamoDbTicketRegistryFacilitator.get) with an id whose prefix (e.g. the part before the '-' separator, like 'TGT' or 'ST') has no TicketDefinition in the TicketCatalog — typically because the ticket-definition catalog was not initialized for that ticket type, or the id is malformed/foreign.

Common situations: Custom ticket types registered in DynamoDB but not registered with the TicketCatalog in the current CAS build; corrupted or hand-edited ticket ids in the table; lookups of tickets issued by a different CAS version or module whose definitions are not on the classpath; calling get with an arbitrary string instead of a real ticket id.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08). Data as JSON: /api/errors/2dd741c4af5b0dfa. Report an issue: GitHub.

Appendix: source

Thrown at support/cas-server-support-dynamodb-ticket-registry/src/main/java/org/apereo/cas/ticket/registry/DynamoDbTicketRegistryFacilitator.java:256

     * @param ticketId        the ticket id
     * @param encodedTicketId the encoded ticket id
     * @return the ticket
     */
    public Ticket get(final String ticketId, final String encodedTicketId) {
        val metadata = this.ticketCatalog.find(ticketId);
        if (metadata != null) {
            val keys = new HashMap<String, AttributeValue>();
            keys.put(ColumnNames.ID.getColumnName(), AttributeValue.builder().s(encodedTicketId).build());
            val request = GetItemRequest.builder().key(keys).tableName(metadata.getProperties().getStorageName()).build();
            LOGGER.debug("Submitting request [{}] to get ticket item [{}]", request, ticketId);
            val returnItem = amazonDynamoDBClient.getItem(request).item();
            if (returnItem != null && !returnItem.isEmpty()) {
                val ticket = deserializeTicket(returnItem);
                LOGGER.debug("Located ticket [{}]", ticket);
                return ticket;
            }
        } else {
            LOGGER.warn("No ticket definition could be found in the catalog to match [{}]", ticketId);
        }
        return null;
    }

    /**
     * Put.
     *
     * @param toSave the to save
     */
    public void put(final Stream<TicketPayload> toSave) {
        val queue = new HashMap<String, List<WriteRequest>>();
        val count = new AtomicLong(0);
        toSave.forEach(entry -> {
            val metadata = ticketCatalog.find(entry.getOriginalTicket());
            val entries = queue.computeIfAbsent(metadata.getProperties().getStorageName(), __ -> new ArrayList<>());
            entries.add(WriteRequest.builder().putRequest(buildPutRequest(entry)).build());
            count.getAndIncrement();
            if (count.get() >= BATCH_PUT_REQUEST_LIMIT) {

View on GitHub (pinned to e7288fc434)