{"record":{"id":"e49d21346ff3be57","repo":"quarkusio/quarkus","slug":"s-oidcclient-can-not-complete-the-s-grant-reques","errorCode":null,"errorMessage":"%s OidcClient can not complete the %s grant request because a %s client_assertion is missing","messagePattern":"(.+?) OidcClient can not complete the (.+?) grant request because a (.+?) client_assertion is missing","errorType":"exception","errorClass":"OidcClientException","httpStatus":null,"severity":"error","filePath":"extensions/oidc-client/runtime/src/main/java/io/quarkus/oidc/client/runtime/OidcClientImpl.java","lineNumber":230,"sourceCode":"            request.putHeader(AUTHORIZATION_HEADER, clientSecretBasicAuthScheme);\n            if (hasClientSecretProvider()) {\n                credentialsToRetry = PreparedPostRequest.CredentialsToRetry.CLIENT_SECRET_BASIC_AUTH_SCHEME;\n            }\n        } else if (jwtAssertionProvided) {\n            String clientAssertion = additionalGrantParameters.get(OidcConstants.CLIENT_ASSERTION);\n            if (clientAssertion == null) {\n                clientAssertion = asyncCredentials.clientAssertion;\n                if (clientAssertion != null) {\n                    body.set(OidcConstants.CLIENT_ASSERTION, clientAssertion);\n                }\n            }\n            if (clientAssertion == null) {\n                String errorMessage = String.format(\n                        \"%s OidcClient can not complete the %s grant request because a %s client_assertion is missing\",\n                        oidcConfig.id().get(), (isRefresh(op) ? OidcConstants.REFRESH_TOKEN_GRANT : grantType),\n                        OidcCommonUtils.getClientAssertionTokenType(oidcConfig.credentials().jwt().source()));\n                LOG.error(errorMessage);\n                throw new OidcClientException(errorMessage);\n            }\n            body.set(OidcConstants.CLIENT_ASSERTION_TYPE,\n                    clientAssertionProvider != null ? clientAssertionProvider.getClientAssertionType()\n                            : OidcConstants.JWT_BEARER_CLIENT_ASSERTION_TYPE);\n        } else if (clientJwtKey != null) {\n            // if it is a refresh then a map has already been copied\n            body = !isRefresh(op) ? copyMultiMap(body) : body;\n            String jwt = OidcCommonUtils.signJwtWithKey(oidcConfig, tokenRequestUri, clientJwtKey);\n\n            if (OidcCommonUtils.isClientSecretPostJwtAuthRequired(oidcConfig.credentials())) {\n                body.add(OidcConstants.CLIENT_ID, oidcConfig.clientId().get());\n                body.add(OidcConstants.CLIENT_SECRET, jwt);\n            } else if (OidcCommonUtils.isJwtAssertion(oidcConfig.credentials())) {\n                if (!OidcConstants.JWT_BEARER_GRANT_TYPE.equals(body.get(OidcConstants.GRANT_TYPE))) {\n                    String errorMessage = String.format(\n                            \"%s OidcClient wants to use JWT bearer grant assertion but has a wrong grant type %s configured.\"\n                                    + \" You must set 'quarkus.oidc-client.grant.type' property to 'jwt'.\",\n                            oidcConfig.id().get(), body.get(OidcConstants.GRANT_TYPE));","sourceCodeStart":212,"sourceCodeEnd":248,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/oidc-client/runtime/src/main/java/io/quarkus/oidc/client/runtime/OidcClientImpl.java#L212-L248","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before\nquarkus.oidc-client.credentials.jwt.source=key\n# (no key configured -> assertion missing)\n\n# after\nquarkus.oidc-client.credentials.jwt.source=key\nquarkus.oidc-client.credentials.jwt.key-location=classpath:privateKey.pem","handlingStrategy":"validation","validationCode":"if (config.credentials().jwt().source() != JwtSource.NONE && config.credentials().jwt().keyStore().isEmpty() && config.credentials().jwt().key().isEmpty() && config.credentials().jwt().tokenPath().isEmpty()) {\n    throw new IllegalArgumentException(\"JWT source configured but no key/key-store/token-path set for OIDC client \" + config.id().orElse(\"\"));\n}","typeGuard":"boolean hasClientAssertionMaterial(OidcClientConfig c) {\n    return c.credentials().jwt().key().isPresent() || c.credentials().jwt().keyStore().isPresent() || c.credentials().jwt().tokenPath().isPresent();\n}","tryCatchPattern":"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; }","preventionTips":["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"],"tags":["oidc","config","jwt","client-assertion"],"backgroundTag":"missing-oidc-client-assertion","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}