quarkusio/quarkus · error · ConfigurationException

'public-key' property can only be used with the 'service' ap

Error message

'public-key' property can only be used with the 'service' applications

What it means

A local public key (public-key property) enables offline JWT verification, which only applies to service applications validating bearer access tokens. If the tenant is not a service app (e.g. web-app or hybrid), Quarkus throws this ConfigurationException in createTenantContextFromPublicKey because web-app code flows require a full OIDC provider connection.

Source

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

            return "quarkus.oidc." + tenantId + "." + configSubKey;
        }
    }

    private boolean enableUserInfo(OidcTenantConfig oidcConfig) {
        Optional<Boolean> userInfoRequired = oidcConfig.authentication().userInfoRequired();
        if (userInfoRequired.isPresent()) {
            if (!userInfoRequired.get()) {
                return false;
            }
        } else {
            oidcConfig.authentication.setUserInfoRequired(true);
        }
        return true;
    }

    private Uni<TenantConfigContext> createTenantContextFromPublicKey(OidcTenantConfig oidcConfig) {
        if (!OidcUtils.isServiceApp(oidcConfig)) {
            throw new ConfigurationException("'public-key' property can only be used with the 'service' applications");
        }
        LOG.debug("'public-key' property for the local token verification is set,"
                + " no connection to the OIDC server will be created");

        return TenantConfigContext.createReady(new OidcProvider(oidcConfig.publicKey().get(), oidcConfig), oidcConfig);
    }

    private Uni<TenantConfigContext> createTenantContextToVerifyCertChain(OidcTenantConfig oidcConfig) {
        if (!OidcUtils.isServiceApp(oidcConfig)) {
            throw new ConfigurationException(
                    "Currently only 'service' applications can be used to verify tokens with inlined certificate chains");
        }

        return TenantConfigContext.createReady(new OidcProvider(null, oidcConfig), oidcConfig);
    }

    private OIDCException toOidcException(Throwable cause, String authServerUrl, String tenantId) {
        final String message = OidcCommonUtils.formatConnectionErrorMessage(authServerUrl);

View on GitHub (pinned to e1c734241f)

Solutions

  1. Set quarkus.oidc.application-type=service so the public key can be used for local verification
  2. Remove quarkus.oidc.public-key and connect to the OIDC provider (web-app flow)
  3. Use per-tenant config: quarkus.oidc.<tenant>.public-key with quarkus.oidc.<tenant>.application-type=service

Example fix

// before
quarkus.oidc.application-type=web-app
quarkus.oidc.public-key=MIIBIjANBg...
// after
quarkus.oidc.application-type=service
quarkus.oidc.public-key=MIIBIjANBg...
Defensive patterns

Strategy: validation

Validate before calling

if (config.publicKey().isPresent() && !OidcUtils.isServiceApp(config)) {
    throw new IllegalArgumentException("public-key requires application-type=service");
}

Type guard

boolean isPublicKeyServiceApp(OidcTenantConfig c) {
    return c.publicKey().isPresent() && OidcUtils.isServiceApp(c);
}

Prevention

When it happens

Trigger: createTenantContext detects a set publicKey but OidcUtils.isServiceApp(oidcConfig) returns false (applicationType not service, or web-app discovery settings present).

Common situations: Setting quarkus.oidc.public-key in an application whose default application-type is web-app; reusing a service tenant config with public key after switching types; hybrid app with public key expectation.

Related errors


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