quarkusio/quarkus · error · ConfigurationException
Only one of client secret or JWT bearer/SPIFFE authenticatio
Error message
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
What it means
credentials.jwt.source=bearer (or spiffe-jwt) means the JWT is fetched from an external source and sent as a bearer token, which is incompatible with configuring a client secret. verifyCommonConfiguration fails startup when both a client secret and a bearer/spiffe JWT source are set, listing the configured source value in the message.
Source
Thrown at extensions/oidc-common/runtime/src/main/java/io/quarkus/oidc/common/runtime/OidcCommonUtils.java:223
boolean jwtBearerOrSpiffe = creds.jwt().source() == Source.BEARER
|| creds.jwt().source() == Source.SPIFFE_JWT;
if (jwtSecretConfigured && jwtKeyConfigured) {
throw new ConfigurationException(
String.format(
"Only one of JWT secret or JWT private key authentication methods can be configured,"
+ " 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()));View on GitHub (pinned to e1c734241f)
Solutions
- Remove credentials.client.secret if the client should use bearer/spiffe JWT tokens
- Or remove/rename credentials.jwt.source if the client should authenticate with the secret
- Ensure no environment variable or profile supplies the second property
Example fix
# before quarkus.oidc-client.credentials.client-secret.value=secret123 quarkus.oidc-client.credentials.jwt.source=bearer # after quarkus.oidc-client.credentials.jwt.source=bearer quarkus.oidc-client.credentials.jwt.token-path=/var/run/secrets/token
Defensive patterns
Strategy: validation
Validate before calling
String source = ConfigProvider.getConfig().getOptionalValue("quarkus.oidc-client.credentials.jwt.source", String.class).orElse(null);
boolean clientSecret = ConfigProvider.getConfig().getOptionalValue("quarkus.oidc-client.credentials.client-secret.value", String.class).isPresent();
if (clientSecret && ("bearer".equals(source) || "spiffe-jwt".equals(source)))
throw new IllegalStateException("Client secret cannot be combined with jwt.source=" + source); Try / catch
try {
start();
} catch (ConfigurationException e) {
if (e.getMessage().contains("bearer/SPIFFE")) log.error("Remove client secret or the jwt.source setting");
throw e;
} Prevention
- When enabling bearer/spiffe-jwt source, remove client-secret properties in the same change
- Check env-var-injected secrets (e.g. K8s secrets) for conflicts
- Keep credentials config blocks minimal and source-specific
When it happens
Trigger: Setting quarkus.oidc[-client].credentials.jwt.source=bearer (or spiffe-jwt) while also configuring credentials.client.secret under the same prefix.
Common situations: A default secret config inherited by a client switched to externally-provided bearer tokens; copy-pasting a named-provider block that keeps both properties; platform team injects secrets via env vars while app config enables bearer JWT.
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 JWT private key or JWT bearer/SPIFFE authenticat
- '%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/0524994e45fb41b1.
Report an issue: GitHub.