quarkusio/quarkus · error · ConfigurationException
Only one of JWT private key or JWT bearer/SPIFFE authenticat
Error message
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
What it means
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.
Source
Thrown at extensions/oidc-common/runtime/src/main/java/io/quarkus/oidc/common/runtime/OidcCommonUtils.java:230
+ " but '%1$scredentials.jwt' has both a JWT secret and a JWT key property set",
configPrefix));
}
if (clientSecretConfigured && jwtKeyConfigured) {
throw new ConfigurationException(
String.format(
"Only one of client secret or JWT private key authentication methods can be configured,"
+ " but '%1$scredentials' has both a client secret and a JWT key property set",
configPrefix));
}
if (clientSecretConfigured && jwtBearerOrSpiffe) {
throw new ConfigurationException(
String.format(
"Only one of client secret or JWT bearer/SPIFFE authentication methods can be configured,"
+ " but '%1$scredentials' has both a client secret and '%1$scredentials.jwt.source=%2$s' set",
configPrefix, creds.jwt().source().toString().toLowerCase()));
}
if (jwtKeyConfigured && jwtBearerOrSpiffe) {
throw new ConfigurationException(
String.format(
"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",
configPrefix, creds.jwt().source().toString().toLowerCase()));
}
if (jwtSecretConfigured && jwtBearerOrSpiffe) {
throw new ConfigurationException(
String.format(
"Only one of JWT secret or JWT bearer/SPIFFE authentication methods can be configured,"
+ " but '%1$scredentials' has both a JWT secret and '%1$scredentials.jwt.source=%2$s' set",
configPrefix, creds.jwt().source().toString().toLowerCase()));
}
Credentials.Jwt jwt = creds.jwt();
if (jwt.source() == Source.BEARER) {
if (isServerConfig && jwt.tokenPath().isEmpty()) {
throw new ConfigurationException(
String.format("'%scredentials.jwt.token-path' must be set when the JWT source is 'bearer'",View on GitHub (pinned to e1c734241f)
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
Example fix
# before quarkus.oidc-client.credentials.jwt.key-file=/etc/certs/key.pem quarkus.oidc-client.credentials.jwt.source=spiffe-jwt # after quarkus.oidc-client.credentials.jwt.source=spiffe-jwt
Defensive patterns
Strategy: validation
Validate before calling
String source = ConfigProvider.getConfig().getOptionalValue("quarkus.oidc-client.credentials.jwt.source", String.class).orElse(null);
boolean jwtKey = ConfigProvider.getConfig().getOptionalValue("quarkus.oidc-client.credentials.jwt.key-file", String.class).isPresent();
if (jwtKey && ("bearer".equals(source) || "spiffe-jwt".equals(source)))
throw new IllegalStateException("JWT key cannot be combined with jwt.source=" + source); Try / catch
try {
start();
} catch (ConfigurationException e) {
if (e.getMessage().contains("both a JWT key property")) log.error("Remove jwt key props or reset jwt.source");
throw e;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Only one of JWT secret or JWT private key authentication met
- Only one of client secret or JWT bearer/SPIFFE authenticatio
- '%scredentials.jwt.token-path' must be set when the JWT sour
- ISSUED_AT_INVALID_PAST
- Cannot get token for tenant '%s' because a %s client_asserti
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/359544049bede88a.
Report an issue: GitHub.