quarkusio/quarkus · error · ConfigurationException

Only one of client secret or JWT private key authentication

Error message

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

What it means

The client secret can be used for basic/POST client authentication or to sign a secret-based JWT, while credentials.jwt.key* selects private-key JWT authentication. verifyCommonConfiguration throws when a client secret and a JWT private-key property are configured together, as only one authentication method can apply to the token request.

Source

Thrown at extensions/oidc-common/runtime/src/main/java/io/quarkus/oidc/common/runtime/OidcCommonUtils.java:216

            throw new ConfigurationException(
                    String.format(
                            "Only one of '%1$scredentials.jwt.key', '%1$scredentials.jwt.key-file'"
                                    + " or '%1$scredentials.jwt.key-store-file' can be configured",
                            configPrefix));
        }
        boolean jwtKeyConfigured = jwtKeyPropsCount == 1;
        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()));

View on GitHub (pinned to e1c734241f)

Solutions

  1. Choose one method: keep the client secret and remove credentials.jwt.key*, or keep the key property and remove credentials.client.secret
  2. Verify no profile or env var re-introduces the removed property
  3. Restart and confirm startup passes the configuration verification

Example fix

# before
quarkus.oidc-client.credentials.client-secret.value=secret123
quarkus.oidc-client.credentials.jwt.key-file=/etc/certs/key.pem

# after
quarkus.oidc-client.credentials.jwt.key-file=/etc/certs/key.pem
Defensive patterns

Strategy: validation

Validate before calling

boolean clientSecret = ConfigProvider.getConfig().getOptionalValue("quarkus.oidc-client.credentials.client-secret.value", String.class).isPresent();
boolean jwtKey = ConfigProvider.getConfig().getOptionalValue("quarkus.oidc-client.credentials.jwt.key-file", String.class).isPresent();
if (clientSecret && jwtKey) throw new IllegalStateException("Use either a client secret or a JWT private key");

Try / catch

try {
    start();
} catch (ConfigurationException e) {
    if (e.getMessage().contains("both a client secret and a JWT key")) log.error("Drop the client-secret or the jwt.key property");
    throw e;
}

Prevention

When it happens

Trigger: At startup, credentials.client.secret (or similar client secret property) is set and simultaneously one of credentials.jwt.key, credentials.jwt.key-file, credentials.jwt.key-store-file is set under the same config prefix.

Common situations: Hardening a secret-authenticated client by adding a JWT key without removing the secret; provider migration where both old and new credential styles remain; duplicated config blocks in named-provider sections.

Understand the failure class

Related errors


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