quarkusio/quarkus · error · OidcClientException
%s OidcClient wants to use JWT bearer grant assertion but ha
Error message
%s OidcClient wants to use JWT bearer grant assertion but has a wrong grant type %s configured. You must set 'quarkus.oidc-client.grant.type' property to 'jwt'.
What it means
OidcClientImpl.preparePostRequest throws this when the client is set up to use a JWT bearer grant assertion but the configured grant type is not 'jwt'. The JWT bearer grant requires quarkus.oidc-client.grant.type=jwt so the assertion goes into the grant itself; with any other grant type the token request would be invalid.
Source
Thrown at extensions/oidc-client/runtime/src/main/java/io/quarkus/oidc/client/runtime/OidcClientImpl.java:250
body.set(OidcConstants.CLIENT_ASSERTION_TYPE,
clientAssertionProvider != null ? clientAssertionProvider.getClientAssertionType()
: OidcConstants.JWT_BEARER_CLIENT_ASSERTION_TYPE);
} else if (clientJwtKey != null) {
// if it is a refresh then a map has already been copied
body = !isRefresh(op) ? copyMultiMap(body) : body;
String jwt = OidcCommonUtils.signJwtWithKey(oidcConfig, tokenRequestUri, clientJwtKey);
if (OidcCommonUtils.isClientSecretPostJwtAuthRequired(oidcConfig.credentials())) {
body.add(OidcConstants.CLIENT_ID, oidcConfig.clientId().get());
body.add(OidcConstants.CLIENT_SECRET, jwt);
} else if (OidcCommonUtils.isJwtAssertion(oidcConfig.credentials())) {
if (!OidcConstants.JWT_BEARER_GRANT_TYPE.equals(body.get(OidcConstants.GRANT_TYPE))) {
String errorMessage = String.format(
"%s OidcClient wants to use JWT bearer grant assertion but has a wrong grant type %s configured."
+ " You must set 'quarkus.oidc-client.grant.type' property to 'jwt'.",
oidcConfig.id().get(), body.get(OidcConstants.GRANT_TYPE));
LOG.error(errorMessage);
throw new OidcClientException(errorMessage);
}
body.add(OidcConstants.JWT_BEARER_GRANT_ASSERTION, jwt);
} else {
body.add(OidcConstants.CLIENT_ASSERTION_TYPE, OidcConstants.JWT_BEARER_CLIENT_ASSERTION_TYPE);
body.add(OidcConstants.CLIENT_ASSERTION, jwt);
}
} else if (OidcCommonUtils.isClientSecretPostAuthRequired(oidcConfig.credentials())) {
body = !isRefresh(op) ? copyMultiMap(body) : body;
body.set(OidcConstants.CLIENT_ID, oidcConfig.clientId().get());
body.set(OidcConstants.CLIENT_SECRET, clientSecret);
if (hasClientSecretProvider()) {
credentialsToRetry = PreparedPostRequest.CredentialsToRetry.CLIENT_SECRET;
}
} else {
body = !isRefresh(op) ? copyMultiMap(body) : body;
body = copyMultiMap(body).set(OidcConstants.CLIENT_ID, oidcConfig.clientId().get());
}
if (!additionalGrantParameters.isEmpty()) {View on GitHub (pinned to e1c734241f)
Solutions
- Set quarkus.oidc-client.grant.type=jwt
- If a different grant (e.g. client_credentials) is intended, remove the JWT bearer grant assertion configuration
- Check for named-client configs (quarkus.oidc-client.<name>.grant.type) overriding the intended value
Example fix
# before quarkus.oidc-client.grant.type=client quarkus.oidc-client.credentials.jwt.source=token # after quarkus.oidc-client.grant.type=jwt quarkus.oidc-client.credentials.jwt.source=token
Defensive patterns
Strategy: validation
Validate before calling
if (usesJwtBearerAssertion && !"jwt".equals(config.grant().type())) {
throw new IllegalArgumentException("grant.type must be 'jwt' when JWT bearer grant assertion is configured");
} Type guard
boolean isJwtGrant(OidcClientConfig c) {
return OidcConfig.Grant.JWT.equals(c.grant().type());
} Try / catch
try { return client.getTokens().await().indefinitely(); } catch (OidcClientException e) { if (e.getMessage().contains("wrong grant type")) { throw new ConfigurationException("Set quarkus.oidc-client.grant.type=jwt", e); } throw e; } Prevention
- Keep grant.type and credentials.jwt settings consistent
- Review named-client configs for overrides
- Test token acquisition in dev mode before deploying
When it happens
Trigger: quarkus.oidc-client.grant.type is set to something other than 'jwt' (e.g. client or password) while the client is also configured to produce/use a JWT bearer grant assertion (credentials.jwt with grant assertion usage), then getTokens() is called.
Common situations: Copy-pasting client config from a client-credentials example and adding jwt assertion settings; accidentally leaving grant.type at 'client' default while intending a jwt bearer grant; upgrading and changing grant types without updating assertion config.
Related errors
- %s OidcClient can not complete the %s grant request because
- When using a key store, the `quarkus.oidc-client.credentials
- Key is null
- Unsupported signature algorithm
- 'credentials.jwt.source' is set to 'spiffe-jwt', but no audi
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/4f2b300d0a5013e5.
Report an issue: GitHub.