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

  1. Set quarkus.oidc.credentials.jwt.token-path to the file containing the bearer token, e.g. /var/run/secrets/kubernetes.io/serviceaccount/token
  2. If you meant a client config, configure it under quarkus.oidc-client.credentials.jwt.token-path where the check does not apply
  3. 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

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


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/633756fa4129c056. Report an issue: GitHub.