quarkusio/quarkus · error · OIDCException
Application 'web-app' type is only supported if access token
Error message
Application 'web-app' type is only supported if access token is the source of roles
What it means
KeycloakPolicyEnforcerUtil.createPolicyEnforcer rejects OidcTenantConfig whose applicationType is web-app unless the role source is the access token. The policy enforcer relies on claims from the access token to make authorization decisions, so role sources like idtoken or userinfo are incompatible with web-app type.
Source
Thrown at extensions/keycloak-authorization/runtime/src/main/java/io/quarkus/keycloak/pep/runtime/KeycloakPolicyEnforcerUtil.java:41
import io.quarkus.proxy.ProxyConfiguration;
import io.quarkus.proxy.ProxyConfigurationRegistry;
import io.quarkus.runtime.configuration.ConfigurationException;
public final class KeycloakPolicyEnforcerUtil {
private KeycloakPolicyEnforcerUtil() {
// UTIL CLASS
}
static PolicyEnforcer createPolicyEnforcer(OidcTenantConfig oidcConfig,
KeycloakPolicyEnforcerTenantConfig keycloakPolicyEnforcerConfig,
TlsConfigSupport tlsConfigSupport,
ProxyConfigurationRegistry proxyConfigurationRegistry) {
if (oidcConfig.applicationType()
.orElse(OidcTenantConfig.ApplicationType.SERVICE) == OidcTenantConfig.ApplicationType.WEB_APP
&& oidcConfig.roles().source().orElse(null) != OidcTenantConfig.Roles.Source.accesstoken) {
throw new OIDCException("Application 'web-app' type is only supported if access token is the source of roles");
}
AdapterConfig adapterConfig = new AdapterConfig();
String authServerUrl = oidcConfig.authServerUrl().get();
try {
adapterConfig.setRealm(authServerUrl.substring(authServerUrl.lastIndexOf('/') + 1));
adapterConfig.setAuthServerUrl(authServerUrl.substring(0, authServerUrl.lastIndexOf("/realms")));
} catch (Exception cause) {
throw new ConfigurationException("Failed to parse the realm name.", cause);
}
adapterConfig.setResource(oidcConfig.clientId().get());
adapterConfig.setCredentials(getCredentials(oidcConfig));
if (!tlsConfigSupport.useTlsRegistry()) {
if (tlsConfigSupport.isGlobalTrustAll()) {
adapterConfig.setDisableTrustManager(true);View on GitHub (pinned to e1c734241f)
Solutions
- Set quarkus.oidc.roles.source=accesstoken so roles come from the access token.
- Or change quarkus.oidc.application-type=service if the app does not need web-app behavior.
- Remove conflicting roles.source configuration (leave default) when using the policy enforcer with web-app type.
Example fix
// before quarkus.oidc.application-type=web-app quarkus.oidc.roles.source=userinfo // after quarkus.oidc.application-type=web-app quarkus.oidc.roles.source=accesstoken
Defensive patterns
Strategy: validation
Validate before calling
// fail fast at startup if config is incompatible
OidcTenantConfig c = /* resolved tenant config */;
boolean webApp = c.applicationType().orElse(OidcTenantConfig.ApplicationType.SERVICE)
== OidcTenantConfig.ApplicationType.WEB_APP;
boolean badSource = c.roles().source().isPresent()
&& c.roles().source().get() != OidcTenantConfig.Roles.Source.accesstoken;
if (webApp && badSource) throw new IllegalStateException("Set roles.source=accesstoken for web-app + policy enforcer"); Try / catch
try {
policyEnforcer = KeycloakPolicyEnforcerUtil.createPolicyEnforcer(...);
} catch (OIDCException e) {
if (e.getMessage().contains("access token is the source of roles")) {
log.error("Set quarkus.oidc.roles.source=accesstoken or application-type=service");
}
throw e;
} Prevention
- When enabling the policy enforcer, audit quarkus.oidc.roles.source settings.
- Do not copy web-app role-source config (userinfo/idtoken) into policy-enforcer apps.
- Document that web-app + policy enforcer requires access-token roles.
When it happens
Trigger: Configuring quarkus.oidc.application-type=web-app (or leaving tenant config resolving to WEB_APP) together with quarkus.oidc.roles.source=user-id-token or =userinfo (or any source other than accesstoken) while the policy enforcer is enabled.
Common situations: Copying OIDC web-app role config (roles.source=userinfo) into an application that also enables quarkus.keycloak.policy-enforcer.enabled=true; switching an app from service to web-app type without revisiting role source.
Related errors
- Failed to parse the realm name.
- Failed to find a matching OidcTenantConfig for tenant:
- Failed to create Keycloak Admin client SSLContext
- Failed to load truststore
- Failed to load keystore
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/a543f310777fdb11.
Report an issue: GitHub.