quarkusio/quarkus · error · RuntimeException

Invalid session expired page redirect

Error message

Invalid session expired page redirect

What it means

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.

Source

Thrown at integration-tests/oidc-code-flow/src/main/java/io/quarkus/it/keycloak/TenantRefresh.java:51

    @GET
    @Path("/session-expired-page")
    public String sessionExpired(@CookieParam("session_expired") String sessionExpired,
            @QueryParam("session-expired") boolean expired, @QueryParam("redirect-filtered") String filtered)
            throws Exception {
        if (expired && filtered.equals("true,")) {
            // Cookie format: jwt|<tenant id>

            String[] pair = sessionExpired.split("\\|");
            OidcTenantConfig oidcConfig = tenantConfig.getStaticTenant(pair[1]).getOidcTenantConfig();
            JsonWebToken jwt = new DefaultJWTParser().decrypt(pair[0], oidcConfig.credentials.secret.get());

            OidcUtils.removeCookie(context, oidcConfig, "session_expired");

            return jwt.getClaim(Claims.preferred_username) + ", your session has expired. "
                    + "Please login again at http://localhost:8081/" + oidcConfig.tenantId.get();
        }

        throw new RuntimeException("Invalid session expired page redirect");
    }
}

View on GitHub (pinned to e1c734241f)

Solutions

  1. Start from the OIDC session-expired redirect flow so the filter sets the required cookie/attributes before this endpoint runs
  2. Verify SessionExpiredOidcRedirectFilter is registered and passes its tenant/URI checks (see its own guards)
  3. Confirm the session-expired page path and tenant config match between filter and resource

Example fix

// before
throw new RuntimeException("Invalid session expired page redirect");
// after
if (!isSessionExpiredRedirect(context)) {
    // redirect the user into the proper flow instead of failing
    return Response.seeOther(URI.create("/session-expired-page")).build();
}
Defensive patterns

Strategy: validation

Validate before calling

Cookie sessionExpired = headers.getCookies().get("session_expired");
if (sessionExpired == null) {
    // not a genuine session-expired redirect; route user to /session-expired-page first
}

Try / catch

try {
    given().get("/tenant-refresh/session-expired");
} catch (RuntimeException e) {
    if (e.getMessage().contains("Invalid session expired page redirect")) {
        // required markers missing; verify SessionExpiredOidcRedirectFilter ran
    }
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/6c2e72da9b2638fd. Report an issue: GitHub.