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
- Verify the ticket id is well-formed and its prefix matches a known ticket type (TGT-, ST-, PGT-, etc.).
- Ensure the TicketCatalog is initialized with a TicketDefinition for that prefix (check TicketCatalogConfigurer beans / cas.ticket.* configuration).
- Confirm the module that defines the ticket type (e.g. core-tickets, support-oauth) is on the classpath of the running webapp.
- 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
- Register a TicketDefinition for every custom ticket type your application writes to the registry.
- Validate ticket ids come from trusted sources before lookup.
- Keep ticket-defining modules consistent across all CAS nodes sharing the DynamoDB table.
- Treat a null return as 'unknown ticket type' separately from 'ticket not found' in caller logic.
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
- Ticket [ ] is not registered in the catalog and is…
- e.getMessage() (ResourceNotFoundException logged during…
- Ticket [ ] is not registered in the catalog and is…
- No authentication found for ticket
- Invalid token:
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)