quarkusio/quarkus · error · ConfigurationException

Either 'jwks-path' or 'introspection-path' properties must b

Error message

Either 'jwks-path' or 'introspection-path' properties must be set when the discovery is disabled.

What it means

With discovery disabled, service (bearer token) applications must still be able to validate tokens — either by fetching signing keys from the JWKS endpoint or by introspecting the token at the provider. createTenantContext throws this ConfigurationException when discovery is off, neither jwks-path nor introspection-path is configured, and the tenant does not support only UserInfo.

Source

Thrown at extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/TenantContextFactory.java:258

        if (!oidcConfig.discoveryEnabled().orElse(true)) {
            if (!OidcUtils.isServiceApp(oidcConfig)) {
                if (oidcConfig.authorizationPath().isEmpty() || oidcConfig.tokenPath().isEmpty()) {
                    String authorizationPathProperty = getConfigPropertyForTenant(tenantId, "authorization-path");
                    String tokenPathProperty = getConfigPropertyForTenant(tenantId, "token-path");
                    throw new ConfigurationException(
                            "'web-app' applications must have '" + authorizationPathProperty + "' and '" + tokenPathProperty
                                    + "' properties "
                                    + "set when the discovery is disabled.",
                            Set.of(authorizationPathProperty, tokenPathProperty));
                }
            }
            // JWK and introspection endpoints have to be set for both 'web-app' and 'service' applications
            if (oidcConfig.jwksPath().isEmpty() && oidcConfig.introspectionPath().isEmpty()) {
                if (!oidcConfig.authentication().idTokenRequired().orElse(true)
                        && oidcConfig.authentication().userInfoRequired().orElse(false)) {
                    LOG.debugf("tenant %s supports only UserInfo", oidcConfig.tenantId().get());
                } else if (OidcUtils.isServiceApp(oidcConfig)) {
                    throw new ConfigurationException(
                            "Either 'jwks-path' or 'introspection-path' properties must be set when the discovery is disabled.",
                            Set.of("quarkus.oidc.jwks-path", "quarkus.oidc.introspection-path"));
                }
            }
            if (oidcConfig.authentication().userInfoRequired().orElse(false) && oidcConfig.userInfoPath().isEmpty()) {
                String configProperty = getConfigPropertyForTenant(tenantId, "user-info-path");
                throw new ConfigurationException(
                        "UserInfo is required but '" + configProperty + "' is not configured.",
                        Set.of(configProperty));
            }
        }

        if (OidcUtils.isServiceApp(oidcConfig)) {
            if (oidcConfig.token().refreshExpired()) {
                throw new ConfigurationException(
                        "The '" + getConfigPropertyForTenant(tenantId, "token.refresh-expired")
                                + "' property can only be enabled for "
                                + io.quarkus.oidc.runtime.OidcTenantConfig.ApplicationType.WEB_APP

View on GitHub (pinned to e1c734241f)

Solutions

  1. Set quarkus.oidc.jwks-path (e.g. /protocol/openid-connect/certs) to verify JWTs locally.
  2. Or set quarkus.oidc.introspection-path to verify tokens remotely via introspection.
  3. Or re-enable discovery if the provider supports the well-known endpoint.

Example fix

// before
quarkus.oidc.discovery-enabled=false

// after
quarkus.oidc.discovery-enabled=false
quarkus.oidc.jwks-path=/protocol/openid-connect/certs
Defensive patterns

Strategy: validation

Validate before calling

if ("false".equals(config.getProperty("quarkus.oidc.discovery-enabled"))
        && config.getProperty("quarkus.oidc.jwks-path") == null
        && config.getProperty("quarkus.oidc.introspection-path") == null) {
    throw new IllegalStateException("Set jwks-path or introspection-path when discovery is disabled");
}

Prevention

When it happens

Trigger: createTenantContext finds oidcConfig.discoveryEnabled() == false, both oidcConfig.jwksPath().isEmpty() and oidcConfig.introspectionPath().isEmpty(), and the tenant is a service app not configured with idTokenRequired=false + userInfoRequired=true (UserInfo-only tenants are exempted).

Common situations: Disabling discovery for a token-introspecting proxy setup but forgetting introspection-path; an IdP without the well-known endpoint where only the token endpoint was configured; copy-pasting a web-app tenant config (which only needs authorization/token paths) into a service app.

Related errors


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