quarkusio/quarkus · error · ConfigurationException
'%scredentials.jwt.token-path' must be set when the JWT sour
Error message
'%scredentials.jwt.token-path' must be set when the JWT source is 'bearer'
What it means
When credentials.jwt.source=bearer, Quarkus does not generate the client JWT — it reads it from a token file (e.g. a mounted service-account token). If that token-path is not set (and this check applies to server-side OIDC configurations, isServerConfig), startup fails because there is no way to obtain the bearer token.
Source
Thrown at extensions/oidc-common/runtime/src/main/java/io/quarkus/oidc/common/runtime/OidcCommonUtils.java:247
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'",
configPrefix));
}
} else if (jwt.source() == Source.SPIFFE_JWT) {
if (jwt.tokenPath().isEmpty() && Arc.container().select(SpiffeClient.class).isUnsatisfied()) {
throw new ConfigurationException(String.format(
"'%1$scredentials.jwt.source' is set to 'spiffe-jwt', but no SPIFFE JWT-SVID provider is available."
+ " Either set '%1$scredentials.jwt.token-path' to a file containing the JWT-SVID,"
+ " or add the 'quarkus-spiffe-client' extension to fetch JWT-SVIDs"
+ " from the SPIFFE Workload API",
configPrefix));
}
} else if (jwt.source() == Source.CLIENT && jwt.tokenPath().isPresent()) {
throw new ConfigurationException(String.format(
"'%scredentials.jwt.token-path' can only be set when the JWT source is 'bearer' or 'spiffe-jwt'",
configPrefix));
}
}View on GitHub (pinned to e1c734241f)
Solutions
- Set quarkus.oidc.credentials.jwt.token-path to the file containing the bearer token, e.g. /var/run/secrets/kubernetes.io/serviceaccount/token
- If you meant a client config, configure it under quarkus.oidc-client.credentials.jwt.token-path where the check does not apply
- Or drop jwt.source=bearer if the token is not externally supplied
Example fix
# before quarkus.oidc.credentials.jwt.source=bearer # after quarkus.oidc.credentials.jwt.source=bearer quarkus.oidc.credentials.jwt.token-path=/var/run/secrets/kubernetes.io/serviceaccount/token
Defensive patterns
Strategy: validation
Validate before calling
String source = ConfigProvider.getConfig().getOptionalValue("quarkus.oidc.credentials.jwt.source", String.class).orElse(null);
String tokenPath = ConfigProvider.getConfig().getOptionalValue("quarkus.oidc.credentials.jwt.token-path", String.class).orElse(null);
if ("bearer".equals(source) && (tokenPath == null || tokenPath.isBlank()))
throw new IllegalStateException("jwt.source=bearer requires jwt.token-path"); Try / catch
try {
start();
} catch (ConfigurationException e) {
if (e.getMessage().contains("token-path")) log.error("Set jwt.token-path for bearer source");
throw e;
} Prevention
- Always pair jwt.source=bearer with token-path in templates
- Mount and reference the token file (e.g. service-account token) explicitly
- Add a CI startup test so missing token-path fails before deployment
When it happens
Trigger: verifyCommonConfiguration with isServerConfig=true (OIDC server config, e.g. quarkus.oidc.*) and credentials.jwt.source=bearer but credentials.jwt.token-path not set.
Common situations: Enabling bearer source on a quarkus.oidc (server) config but forgetting token-path — note the check is skipped for quarkus.oidc-client configs where path may be optional; typos in property name; K8s volume not mounted so property was never added.
Related errors
- Only one of JWT secret or JWT private key authentication met
- Only one of client secret or JWT bearer/SPIFFE authenticatio
- Only one of JWT private key or JWT bearer/SPIFFE authenticat
- 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/633756fa4129c056.
Report an issue: GitHub.