quarkusio/quarkus · error · AuthenticationFailedException

Access token expires_in property in the session cookie must

Error message

Access token expires_in property in the session cookie must be a number, found %s

What it means

DefaultTokenStateManager stores the access token's expiry (expires_in) in the encrypted/encoded q_session_at cookie. When reading tokens back (getTokens), parseAccessTokenExpiresIn() expects a numeric string; a non-numeric value raises AuthenticationFailedException so the failure is visible in dev mode.

Source

Thrown at extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/DefaultTokenStateManager.java:209

                    OidcUtils.removeCookie(routingContext, oidcConfig, cookieName);
                }
            }

            OidcUtils.removeCookie(routingContext, getRefreshTokenCookie(routingContext, oidcConfig),
                    oidcConfig);
        }
        return CodeAuthenticationMechanism.VOID_UNI;
    }

    private static Long parseAccessTokenExpiresIn(String accessTokenExpiresInString) {
        try {
            return Long.valueOf(accessTokenExpiresInString);
        } catch (NumberFormatException ex) {
            final String error = "Access token expires_in property in the session cookie must be a number, found %s"
                    .formatted(accessTokenExpiresInString);
            LOG.error(error);
            // Make this error message visible in the dev mode
            throw new AuthenticationFailedException(error);
        }
    }

    private static String getAccessTokenCookie(RoutingContext routingContext, OidcTenantConfig oidcConfig) {
        final Map<String, Cookie> cookies = OidcUtils.cookieSetToMap(routingContext.request().cookies());
        return OidcUtils.getSessionCookie(routingContext.data(), cookies, oidcConfig, OidcUtils.SESSION_AT_COOKIE_NAME,
                getAccessTokenCookieName(oidcConfig));
    }

    private static ServerCookie getRefreshTokenCookie(RoutingContext routingContext, OidcTenantConfig oidcConfig) {
        return (ServerCookie) routingContext.request().getCookie(getRefreshTokenCookieName(oidcConfig));
    }

    private static String getAccessTokenCookieName(OidcTenantConfig oidcConfig) {
        String cookieSuffix = OidcUtils.getCookieSuffix(oidcConfig);
        return OidcUtils.SESSION_AT_COOKIE_NAME + cookieSuffix;
    }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Delete the malformed cookies (q_session / q_session_at / q_auth) in the browser or send the user through a fresh login so new cookies are written.
  2. Verify cookie encryption secret/key configuration is stable across replicas and versions so decryption yields the intended format.
  3. Upgrade/align Quarkus versions if cookies were produced by an incompatible OIDC format, or temporarily disable split-tokens strategy to simplify cookie content.

Example fix

// before (client sends corrupted cookie)
Cookie: q_session_at=abc|not-a-number|scope

// after - clear cookies and re-authenticate; ensure identical
// quarkus.oidc.token-state-manager.encryption-secret across all replicas
quarkus.oidc.token-state-manager.encryption-secret=same-value-everywhere
Defensive patterns

Strategy: try-catch

Validate before calling

// Client-side sanity check before reusing an old session cookie
String[] parts = atCookieValue.split("\\|");
boolean wellFormed = parts.length >= 2 && (parts[1].isEmpty() || parts[1].matches("\\d+"));
if (!wellFormed) { clearCookie("q_session_at"); /* force re-login */ }

Try / catch

try {
    chain.doFilter(request, response);
} catch (AuthenticationFailedException e) {
    if (e.getMessage() != null && e.getMessage().contains("expires_in")) {
        // drop cookies and redirect to re-authenticate
    }
    throw e;
}

Prevention

When it happens

Trigger: A request presents a session access-token cookie (q_session_at) whose second '|' segment is not parseable by Long.valueOf - e.g. a corrupted, hand-edited, truncated, or wrongly-encoded cookie value (when encryption is disabled the fields are base64url/plain pipe-separated and easy to tamper with).

Common situations: Cookie truncated by proxies or size limits; stale cookies written by a different Quarkus/OIDC version with a different cookie format; manual cookie manipulation or test tooling sending malformed values; encryption key change corrupting decryption producing garbage segments.

Related errors


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