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
- Set quarkus.oidc.application-type=service so the public key can be used for local verification
- Remove quarkus.oidc.public-key and connect to the OIDC provider (web-app flow)
- 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
- Use public-key only in service (bearer) tenants
- Keep a dedicated tenant for local-verification endpoints
- Re-check application-type after migrating between browser and API security
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
- Neither public key nor certificate chain verification modes
- Both public key and certificate chain verification modes are
- The '%s' property can only be set to 'idtoken' for WEB_APP a
- '%s' must be enabled to use '%s'
- UserInfo is required but DefaultTokenStateManager is configu
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/b4d8537b7df07596.
Report an issue: GitHub.