quarkusio/quarkus · error · InternalServerErrorException
'state' query parameter is not available
Error message
'state' query parameter is not available
What it means
The post-logout callback requires the OIDC 'state' query parameter that the provider appends when redirecting back after logout. Quarkus OIDC correlates this state with the q_post_logout cookie. A missing parameter means the callback was not produced by a genuine provider post-logout redirect.
Source
Thrown at integration-tests/oidc-code-flow/src/main/java/io/quarkus/it/keycloak/TenantLogout.java:48
// It is needed for the proactive-auth=false to work: /tenant-logout/logout should match a user initiated logout request
// which must be handled by `CodeAuthenticationMechanism`.
// Adding `@Authenticated` gives control to `CodeAuthenticationMechanism` instead of RestEasy.
@GET
@Authenticated
@Path("logout")
public String getTenantLogoutPath() {
throw new InternalServerErrorException();
}
@GET
@Path("post-logout")
public String postLogout(@QueryParam("state") String postLogoutState) {
Cookie cookie = headers.getCookies().get("q_post_logout_tenant-logout");
if (cookie == null) {
throw new InternalServerErrorException("q_post_logout cookie is not available");
}
if (postLogoutState == null) {
throw new InternalServerErrorException("'state' query parameter is not available");
}
if (!postLogoutState.equals(cookie.getValue())) {
throw new InternalServerErrorException("'state' query parameter is not equal to the q_post_logout cookie value");
}
return "You were logged out, please login again";
}
}
View on GitHub (pinned to e1c734241f)
Solutions
- Complete the full logout flow so the provider redirects back with the state parameter
- Do not call /post-logout directly; start from the logout endpoint
- Check that the post-logout redirect URI given to the provider matches the endpoint exactly
Example fix
// before
if (postLogoutState == null) {
throw new InternalServerErrorException("'state' query parameter is not available");
}
// after
if (postLogoutState == null) {
return "state parameter missing; restart the logout flow";
} Defensive patterns
Strategy: validation
Validate before calling
if (uriInfo.getQueryParameters().getFirst("state") == null) {
// not a genuine provider post-logout callback; redirect to logout start
} Try / catch
try {
given().get("/tenant-logout/post-logout");
} catch (InternalServerErrorException e) {
if (e.getMessage().contains("'state' query parameter")) {
// provider did not echo state; check provider redirect config
}
} Prevention
- Reach post-logout only through the provider's logout redirect
- Ensure post_logout_redirect_uri passed to the provider matches the endpoint
- Avoid bookmarking the post-logout URL
When it happens
Trigger: A request reaches /tenant-logout/post-logout without the ?state=... query parameter — direct navigation, or the provider did not include state in its post-logout redirect.
Common situations: Manually bookmarking or reloading the post-logout URL; provider (Keycloak) configured without post_logout_redirect_uri so state handling differs; interrupted logout flow.
Related errors
- Back-channel logout path cannot contain a wildcard '*' chara
- OIDC tenants '%s' and '%s' share the same back-channel logou
- <RestClientRequestContext.INVOKED_METHOD_PROP> property must
- q_post_logout cookie is not available
- 'state' query parameter is not equal to the q_post_logout co
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/89252ab2bffc9524.
Report an issue: GitHub.