{"record":{"id":"82846a13828b0692","repo":"apereo/cas","slug":"warn-logger-getmessage-throwable-throwable","errorCode":null,"errorMessage":"warn(logger, getMessage(throwable), throwable)","messagePattern":"warn\\(logger, getMessage\\(throwable\\), throwable\\)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"core/cas-server-core-tickets-api/src/main/java/org/apereo/cas/ticket/registry/AbstractTicketRegistry.java","lineNumber":124,"sourceCode":"\n    @Override\n    public @Nullable Ticket getTicket(final String ticketId) {\n        val returnTicket = getTicket(ticketId, ticket -> {\n            if (ticket.isExpired()) {\n                val ticketAgeSeconds = getTicketAgeSeconds(ticket);\n                LOGGER.debug(\"Ticket [{}] has expired according to policy [{}] after [{}] seconds and [{}] uses and will be removed from the ticket registry\",\n                    ticketId, ticket.getExpirationPolicy().getName(), ticketAgeSeconds, ticket.getCountOfUses());\n                val clientInfo = ClientInfoHolder.getClientInfo();\n                if (ticket instanceof final TicketGrantingTicket tgt) {\n                    applicationContext.publishEvent(new CasRequestSingleLogoutEvent(this, tgt, clientInfo));\n                }\n                try {\n                    deleteTicket(ticket);\n                    if (ticket instanceof final TicketGrantingTicket tgt) {\n                        applicationContext.publishEvent(new CasTicketGrantingTicketDestroyedEvent(this, tgt, clientInfo));\n                    }\n                } catch (final Exception e) {\n                    LoggingUtils.warn(LOGGER, e);\n                }\n                return false;\n            }\n            return true;\n        });\n        if (returnTicket != null) {\n            val ticketAgeSeconds = getTicketAgeSeconds(returnTicket);\n            if (ticketAgeSeconds < -1) {\n                LOGGER.warn(\"Ticket created [{}] second(s) in the future. Check time synchronization on all servers.\", ticketAgeSeconds * -1);\n            }\n        }\n        return returnTicket;\n    }\n\n    @Override\n    public <T extends Ticket> T getTicket(final String ticketId, final @NonNull Class<T> clazz) {\n        val ticket = getTicket(ticketId);\n        if (ticket == null) {","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/core/cas-server-core-tickets-api/src/main/java/org/apereo/cas/ticket/registry/AbstractTicketRegistry.java#L106-L142","documentation":"In AbstractTicketRegistry.getTicket, when the retrieved ticket is expired, the registry attempts to delete it and (for TGTs) publish a CasTicketGrantingTicketDestroyedEvent. Any exception during that cleanup is swallowed and logged at warn level via LoggingUtils.warn(logger, throwable). Operationally the getTicket still returns no ticket; this warning indicates the expired-ticket cleanup path failed.","triggerScenarios":"Calling ticketRegistry.getTicket(id) for an expired ticket where deleteTicket(ticket) or the destroyed-event publication throws — e.g. underlying storage (Redis/Mongo/JDBC/Hazelcast) unreachable, serialization failure, or listener error during event publish.","commonSituations":"Transient backend outages during high-traffic validation; deserialization errors of stale tickets in the registry; event listeners throwing inside CasTicketGrantingTicketDestroyedEvent handlers.","solutions":["Inspect the attached throwable (logged via LoggingUtils.warn) to find the root cause — usually ticket-registry backend connectivity or serialization.","Verify the ticket registry store (Redis/Mongo/etc.) is reachable and credentials/network are healthy.","Check registered CasTicketGrantingTicketDestroyedEvent listeners for exceptions they throw; fix or make them defensive.","If stale/deserialization-prone entries accumulate, clean the registry of old tickets; the warning is non-fatal to the caller (ticket is treated as absent)."],"exampleFix":"// before\ntry { deleteTicket(ticket); ... } catch (final Exception e) { LoggingUtils.warn(LOGGER, e); } // hides backend outage\n// after\n// monitor LOGGER.warn from AbstractTicketRegistry and alert on backend exceptions:\n// add health checks/retries for the ticket registry datasource (e.g. Redis ping) instead of relying on swallowed cleanup errors","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// caller: expired ticket simply returns null; guard the null\nTicket t = ticketRegistry.getTicket(id);\nif (t == null) { /* treat as unauthenticated; also alert on AbstractTicketRegistry warn logs */ }","preventionTips":["Monitor warn logs from AbstractTicketRegistry as a signal of ticket-registry backend trouble","Keep CasTicketGrantingTicketDestroyedEvent listeners exception-safe","Add health checks and retries for the ticket registry store"],"tags":["cas","ticket-registry","cleanup","logging"],"backgroundTag":"http-request-failed","analyzedSha":"e7288fc434b4f4505b8452e1a57e8fb3111bb863","analyzedAt":"2026-09-08T15:39:16.015Z","contentChangedAt":"2026-09-08T15:39:16.015Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}