quarkusio/quarkus · error · OidcClientException
%s OidcClient can not complete the %s grant request because
Error message
%s OidcClient can not complete the %s grant request because a %s client_assertion is missing
What it means
This OidcClientException is thrown by OidcClientImpl.preparePostRequest when the client is configured to authenticate with a JWT client assertion (client_credentials or jwt-based credentials), but no assertion could be produced. The assertion normally comes from a configured JWT source (key/certificate/token-path) or a client assertion provider; when both are missing the token request cannot be built.
Source
Thrown at extensions/oidc-client/runtime/src/main/java/io/quarkus/oidc/client/runtime/OidcClientImpl.java:230
request.putHeader(AUTHORIZATION_HEADER, clientSecretBasicAuthScheme);
if (hasClientSecretProvider()) {
credentialsToRetry = PreparedPostRequest.CredentialsToRetry.CLIENT_SECRET_BASIC_AUTH_SCHEME;
}
} else if (jwtAssertionProvided) {
String clientAssertion = additionalGrantParameters.get(OidcConstants.CLIENT_ASSERTION);
if (clientAssertion == null) {
clientAssertion = asyncCredentials.clientAssertion;
if (clientAssertion != null) {
body.set(OidcConstants.CLIENT_ASSERTION, clientAssertion);
}
}
if (clientAssertion == null) {
String errorMessage = String.format(
"%s OidcClient can not complete the %s grant request because a %s client_assertion is missing",
oidcConfig.id().get(), (isRefresh(op) ? OidcConstants.REFRESH_TOKEN_GRANT : grantType),
OidcCommonUtils.getClientAssertionTokenType(oidcConfig.credentials().jwt().source()));
LOG.error(errorMessage);
throw new OidcClientException(errorMessage);
}
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));View on GitHub (pinned to e1c734241f)
Solutions
- Set quarkus.oidc-client.credentials.jwt.key, key-store, or token-path so a client_assertion can be produced
- If using a custom client assertion provider, ensure it returns a non-null assertion
- If JWT client assertion is not intended, remove/reconfigure quarkus.oidc-client.credentials.jwt.source (e.g. use client-secret instead)
- Verify the configured keystore file exists and is readable at runtime
Example fix
# before quarkus.oidc-client.credentials.jwt.source=key # (no key configured -> assertion missing) # after quarkus.oidc-client.credentials.jwt.source=key quarkus.oidc-client.credentials.jwt.key-location=classpath:privateKey.pem
Defensive patterns
Strategy: validation
Validate before calling
if (config.credentials().jwt().source() != JwtSource.NONE && config.credentials().jwt().keyStore().isEmpty() && config.credentials().jwt().key().isEmpty() && config.credentials().jwt().tokenPath().isEmpty()) {
throw new IllegalArgumentException("JWT source configured but no key/key-store/token-path set for OIDC client " + config.id().orElse(""));
} Type guard
boolean hasClientAssertionMaterial(OidcClientConfig c) {
return c.credentials().jwt().key().isPresent() || c.credentials().jwt().keyStore().isPresent() || c.credentials().jwt().tokenPath().isPresent();
} Try / catch
try { tokens = client.getTokens().await().indefinitely(); } catch (OidcClientException e) { if (e.getMessage().contains("client_assertion is missing")) { log.error("Fix credentials.jwt config", e); } throw e; } Prevention
- Always pair credentials.jwt.source with an actual key, key-store, or token-path
- Test OIDC client initialization in a startup health check
- Use quarkus smallrye-jwt keystore conventions consistently
When it happens
Trigger: Calling getTokens/refreshTokens on an OidcClient whose quarkus.oidc-client.credentials.jwt.source implies a client_assertion but no JWT source material is available — e.g. credentials.jwt.source=key with no key store configured, or a token-path that yields nothing, or a client assertion provider returning null.
Common situations: Setting quarkus.oidc-client.credentials.client-secret-path/jwt settings partially (source configured but key file missing); migrating from client-secret to JWT auth and forgetting the keystore; configuring assertion providers that fail to initialize at runtime.
Related errors
- Cannot get token for tenant '%s' because a %s client_asserti
- %s OidcClient wants to use JWT bearer grant assertion but ha
- When using a key store, the `quarkus.oidc-client.credentials
- Key is null
- Unsupported signature algorithm
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/e49d21346ff3be57.
Report an issue: GitHub.