{"record":{"id":"6c2e72da9b2638fd","repo":"quarkusio/quarkus","slug":"invalid-session-expired-page-redirect","errorCode":null,"errorMessage":"Invalid session expired page redirect","messagePattern":"Invalid session expired page redirect","errorType":"http","errorClass":"RuntimeException","httpStatus":500,"severity":"error","filePath":"integration-tests/oidc-code-flow/src/main/java/io/quarkus/it/keycloak/TenantRefresh.java","lineNumber":51,"sourceCode":"    @GET\n    @Path(\"/session-expired-page\")\n    public String sessionExpired(@CookieParam(\"session_expired\") String sessionExpired,\n            @QueryParam(\"session-expired\") boolean expired, @QueryParam(\"redirect-filtered\") String filtered)\n            throws Exception {\n        if (expired && filtered.equals(\"true,\")) {\n            // Cookie format: jwt|<tenant id>\n\n            String[] pair = sessionExpired.split(\"\\\\|\");\n            OidcTenantConfig oidcConfig = tenantConfig.getStaticTenant(pair[1]).getOidcTenantConfig();\n            JsonWebToken jwt = new DefaultJWTParser().decrypt(pair[0], oidcConfig.credentials.secret.get());\n\n            OidcUtils.removeCookie(context, oidcConfig, \"session_expired\");\n\n            return jwt.getClaim(Claims.preferred_username) + \", your session has expired. \"\n                    + \"Please login again at http://localhost:8081/\" + oidcConfig.tenantId.get();\n        }\n\n        throw new RuntimeException(\"Invalid session expired page redirect\");\n    }\n}\n","sourceCodeStart":33,"sourceCodeEnd":54,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/integration-tests/oidc-code-flow/src/main/java/io/quarkus/it/keycloak/TenantRefresh.java#L33-L54","documentation":"TenantRefresh's session-expired handler only accepts requests that arrived via the proper session-expired page redirect (which sets the 'session_expired' cookie and is validated earlier in the method). Reaching the final throw means the request claims to be a session-expired redirect but lacks the expected markers, so it cannot be trusted.","triggerScenarios":"A request reaches the session-expired endpoint without having gone through the /session-expired-page redirect handled by SessionExpiredOidcRedirectFilter (missing session_expired cookie or wrong entry path).","commonSituations":"Direct navigation to the session-expired URL; the redirect filter failing or not registered so markers are never set; token refresh test hitting the endpoint out of order.","solutions":["Start from the OIDC session-expired redirect flow so the filter sets the required cookie/attributes before this endpoint runs","Verify SessionExpiredOidcRedirectFilter is registered and passes its tenant/URI checks (see its own guards)","Confirm the session-expired page path and tenant config match between filter and resource"],"exampleFix":"// before\nthrow new RuntimeException(\"Invalid session expired page redirect\");\n// after\nif (!isSessionExpiredRedirect(context)) {\n    // redirect the user into the proper flow instead of failing\n    return Response.seeOther(URI.create(\"/session-expired-page\")).build();\n}","handlingStrategy":"validation","validationCode":"Cookie sessionExpired = headers.getCookies().get(\"session_expired\");\nif (sessionExpired == null) {\n    // not a genuine session-expired redirect; route user to /session-expired-page first\n}","typeGuard":null,"tryCatchPattern":"try {\n    given().get(\"/tenant-refresh/session-expired\");\n} catch (RuntimeException e) {\n    if (e.getMessage().contains(\"Invalid session expired page redirect\")) {\n        // required markers missing; verify SessionExpiredOidcRedirectFilter ran\n    }\n}","preventionTips":["Enter the session-expired endpoint only via the filter-handled redirect","Keep the filter registered and its tenant/URI guards passing","Share the 'session_expired' cookie name and page path as constants"],"tags":["oidc","session-expired","redirect"],"backgroundTag":"invalid-session-expired-redirect","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-15T02:17:10.978Z"}