quarkusio/quarkus · error · io.quarkus.oidc.runtime.OIDCException
Invalid token type
Error message
Invalid token type
What it means
Quarkus OIDC's OidcUtils.validatePrimaryTokenType validates that the 'typ' header of a JWT matches the configured expected token type. If the token's typ does not equal quarkus.oidc token-type configuration (e.g. expected 'access_token' vs 'id_token' typ), OIDCException 'Invalid token type' is thrown to prevent accepting the wrong token class.
Source
Thrown at extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/OidcUtils.java:496
public static void setSecurityIdentityIntrospection(Builder builder, TokenIntrospection introspectionResult) {
if (introspectionResult != null) {
builder.addAttribute(INTROSPECTION_ATTRIBUTE, introspectionResult);
}
}
public static void setSecurityIdentityConfigMetadata(QuarkusSecurityIdentity.Builder builder,
TenantConfigContext resolvedContext) {
if (resolvedContext.provider().client != null) {
builder.addAttribute(CONFIG_METADATA_ATTRIBUTE, resolvedContext.provider().client.getMetadata());
}
}
public static void validatePrimaryJwtTokenType(Token tokenConfig, JsonObject tokenJson) {
if (tokenJson.containsKey("typ")) {
String type = tokenJson.getString("typ");
if (tokenConfig.tokenType().isPresent() && !tokenConfig.tokenType().get().equals(type)) {
throw new OIDCException("Invalid token type");
} else if ("Refresh".equals(type)) {
// At least check it is not a refresh token issued by Keycloak
throw new OIDCException("Refresh token can only be used with the refresh token grant");
}
}
}
static Uni<Void> removeSessionCookie(RoutingContext context, OidcTenantConfig oidcConfig,
TokenStateManager tokenStateManager) {
List<String> cookieNames = context.get(SESSION_COOKIE_NAME);
if (cookieNames != null) {
LOG.debugf("Remove session cookie names: %s", cookieNames);
StringBuilder cookieValue = new StringBuilder();
for (String cookieName : cookieNames) {
cookieValue.append(removeCookie(context, oidcConfig, cookieName));
}
return tokenStateManager.deleteTokens(context, oidcConfig, cookieValue.toString(),
deleteTokensRequestContext);View on GitHub (pinned to e1c734241f)
Solutions
- Set quarkus.oidc.token.token-type (or TokenConfig tokenType) to match the actual JWT 'typ' header, or remove the setting to skip this check
- Send the correct token type (access token instead of ID token) in the Authorization header
- Check the token's typ header in jwt.io or via debug logging and align configuration
Example fix
// before quarkus.oidc.token.token-type=id_token // after (service receives access tokens) quarkus.oidc.token.token-type=access_token
Defensive patterns
Strategy: validation
Validate before calling
String typ = decodedJwt.getHeader("typ");
if (!expectedType.equals(typ)) throw new IllegalStateException("Send a token with typ=" + expectedType + ", got " + typ); Type guard
boolean hasExpectedTyp(Map<String,Object> jwtHeader, String expected) { return expected.equals(jwtHeader.get("typ")); } Try / catch
try { validate(token); } catch (OIDCException e) { throw new UnauthorizedException("Wrong token type: send the " + expectedTokenType); } Prevention
- Confirm the typ header of tokens your IdP issues
- Match quarkus.oidc.token.token-type to the tokens actually sent
- Never send ID tokens as bearer tokens to resource services
When it happens
Trigger: Verifying a bearer token whose JWT header 'typ' (e.g. 'ID', 'Bearer', 'access') does not match the configured OidcTenantConfig tokenType; passing an ID token where an access token is required (or vice versa).
Common situations: Sending an ID token as a bearer token to a service expecting an access token; Keycloak/other IdP typ headers differing from expectations; explicitly configured quarkus.oidc.token.token-type that mismatches actual tokens.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- %s type can not be used to represent JWT claims in @Singleto
- DPoP proof token signature is invalid
- DPoP access token hash does not match the DPoP proof access
- Opaque access token can not be converted to JsonWebToken
- ISSUED_AT_INVALID_PAST
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/2e2b7e28043e4782.
Report an issue: GitHub.