{"record":{"id":"359544049bede88a","repo":"quarkusio/quarkus","slug":"only-one-of-jwt-private-key-or-jwt-bearer-spiffe-a","errorCode":null,"errorMessage":"Only one of JWT private key or JWT bearer/SPIFFE authentication methods can be configured, but '%1$scredentials' has both a JWT key property and '%1$scredentials.jwt.source=%2$s' set","messagePattern":"Only one of JWT private key or JWT bearer/SPIFFE authentication methods can be configured, but '%1\\$scredentials' has both a JWT key property and '%1\\$scredentials\\.jwt\\.source=%2\\$s' set","errorType":"validation","errorClass":"ConfigurationException","httpStatus":null,"severity":"error","filePath":"extensions/oidc-common/runtime/src/main/java/io/quarkus/oidc/common/runtime/OidcCommonUtils.java","lineNumber":230,"sourceCode":"                                    + \" but '%1$scredentials.jwt' has both a JWT secret and a JWT key property set\",\n                            configPrefix));\n        }\n        if (clientSecretConfigured && jwtKeyConfigured) {\n            throw new ConfigurationException(\n                    String.format(\n                            \"Only one of client secret or JWT private key authentication methods can be configured,\"\n                                    + \" but '%1$scredentials' has both a client secret and a JWT key property set\",\n                            configPrefix));\n        }\n        if (clientSecretConfigured && jwtBearerOrSpiffe) {\n            throw new ConfigurationException(\n                    String.format(\n                            \"Only one of client secret or JWT bearer/SPIFFE authentication methods can be configured,\"\n                                    + \" but '%1$scredentials' has both a client secret and '%1$scredentials.jwt.source=%2$s' set\",\n                            configPrefix, creds.jwt().source().toString().toLowerCase()));\n        }\n        if (jwtKeyConfigured && jwtBearerOrSpiffe) {\n            throw new ConfigurationException(\n                    String.format(\n                            \"Only one of JWT private key or JWT bearer/SPIFFE authentication methods can be configured,\"\n                                    + \" but '%1$scredentials' has both a JWT key property and '%1$scredentials.jwt.source=%2$s' set\",\n                            configPrefix, creds.jwt().source().toString().toLowerCase()));\n        }\n        if (jwtSecretConfigured && jwtBearerOrSpiffe) {\n            throw new ConfigurationException(\n                    String.format(\n                            \"Only one of JWT secret or JWT bearer/SPIFFE authentication methods can be configured,\"\n                                    + \" but '%1$scredentials' has both a JWT secret and '%1$scredentials.jwt.source=%2$s' set\",\n                            configPrefix, creds.jwt().source().toString().toLowerCase()));\n        }\n\n        Credentials.Jwt jwt = creds.jwt();\n        if (jwt.source() == Source.BEARER) {\n            if (isServerConfig && jwt.tokenPath().isEmpty()) {\n                throw new ConfigurationException(\n                        String.format(\"'%scredentials.jwt.token-path' must be set when the JWT source is 'bearer'\",","sourceCodeStart":212,"sourceCodeEnd":248,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/oidc-common/runtime/src/main/java/io/quarkus/oidc/common/runtime/OidcCommonUtils.java#L212-L248","documentation":"A JWT key property (private key signing) and credentials.jwt.source=bearer/spiffe-jwt (externally supplied token) are two mutually exclusive ways of obtaining the client JWT. verifyCommonConfiguration aborts startup when both are configured, since the client cannot both sign its own key-based JWT and use an externally sourced bearer token.","triggerScenarios":"Setting one of credentials.jwt.key / key-file / key-store-file together with credentials.jwt.source=bearer or spiffe-jwt under the same config prefix.","commonSituations":"Switching from signed client assertions to Kubernetes/Workload-provided tokens without deleting key config; combining template blocks from different services; refactoring credentials section left stale properties.","solutions":["Remove the credentials.jwt.key* properties if the token should come from the external bearer/spiffe source","Or reset credentials.jwt.source to client (default) if the client should sign the JWT with its own key","Restart and confirm the configuration verification passes"],"exampleFix":"# before\nquarkus.oidc-client.credentials.jwt.key-file=/etc/certs/key.pem\nquarkus.oidc-client.credentials.jwt.source=spiffe-jwt\n\n# after\nquarkus.oidc-client.credentials.jwt.source=spiffe-jwt","handlingStrategy":"validation","validationCode":"String source = ConfigProvider.getConfig().getOptionalValue(\"quarkus.oidc-client.credentials.jwt.source\", String.class).orElse(null);\nboolean jwtKey = ConfigProvider.getConfig().getOptionalValue(\"quarkus.oidc-client.credentials.jwt.key-file\", String.class).isPresent();\nif (jwtKey && (\"bearer\".equals(source) || \"spiffe-jwt\".equals(source)))\n    throw new IllegalStateException(\"JWT key cannot be combined with jwt.source=\" + source);","typeGuard":null,"tryCatchPattern":"try {\n    start();\n} catch (ConfigurationException e) {\n    if (e.getMessage().contains(\"both a JWT key property\")) log.error(\"Remove jwt key props or reset jwt.source\");\n    throw e;\n}","preventionTips":["Deleting the jwt.key* properties is part of switching to an external token source — do both together","Keep per-source config templates, not one superset config","Validate effective config in CI startup tests"],"tags":["quarkus","oidc","configuration","jwt"],"backgroundTag":"conflicting-configuration-properties","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"}