quarkusio/quarkus · error · io.quarkus.runtime.configuration.ConfigurationException

UserInfo is not required but UserInfo is expected to be the

Error message

UserInfo is not required but UserInfo is expected to be the source of authorization roles

What it means

A tenant configured roles.source=userinfo asks Quarkus to load authorization roles from the IdP's UserInfo endpoint. But UserInfo is only fetched when it is marked required (authentication.userInfoRequired=true or appropriate app type). createTenantContext detects the contradiction — UserInfo is the roles source yet never required — and throws this ConfigurationException.

Source

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

                                + " because either 'TenantConfigResolver' which will resolve tenant configurations is registered"
                                + " or named tenants are configured.");
                        oidcConfig.tenantEnabled = false;
                        return TenantConfigContext.createReady(new OidcProvider(null, null, null), oidcConfig);
                    }
                }
                throw new ConfigurationException(
                        "'" + getConfigPropertyForTenant(tenantId, "auth-server-url") + "' property must be configured");
            }
            OidcCommonUtils.verifyEndpointUrl(oidcConfig.authServerUrl().get());
            OidcCommonUtils.verifyCommonConfiguration(oidcConfig, OidcUtils.isServiceApp(oidcConfig), true);
            verifyAllowedRoutes(oidcConfig, tenantId);
        } catch (ConfigurationException t) {
            return Uni.createFrom().failure(t);
        }

        if (oidcConfig.roles().source().orElse(null) == io.quarkus.oidc.runtime.OidcTenantConfig.Roles.Source.userinfo
                && !enableUserInfo(oidcConfig)) {
            throw new ConfigurationException(
                    "UserInfo is not required but UserInfo is expected to be the source of authorization roles");
        }
        if (oidcConfig.token().verifyAccessTokenWithUserInfo().orElse(false) && !OidcUtils.isWebApp(oidcConfig)
                && !enableUserInfo(oidcConfig)) {
            String propertyName = getConfigPropertyForTenant(tenantId, "token.verify-access-token-with-user-info");
            throw new ConfigurationException("UserInfo is not required but '%s' is enabled".formatted(propertyName));
        }
        if (!oidcConfig.authentication().idTokenRequired().orElse(true) && OidcUtils.isWebApp(oidcConfig)
                && StepUpAuthenticationPolicy.isEnabled()) {
            String propertyName = getConfigPropertyForTenant(tenantId, "authentication.id-token-required");
            // this can be false alarm in case Quarkus application have multiple tenants and 'acr' values are not
            // required for this tenant, which we cannot know
            LOG.warnf("Step Up Authentication is not supported for tenant '%s', because the internal IdToken is"
                    + " generated by Quarkus. Please see the '%s' configuration property documentation for more information",
                    tenantId, propertyName);
        }
        if (!oidcConfig.authentication().idTokenRequired().orElse(true) && !enableUserInfo(oidcConfig)
                && oidcConfig.token().verifyAccessTokenWithUserInfo().orElse(false)) {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Set quarkus.oidc.authentication.user-info-required=true (tenant-scoped variant for named tenants).
  2. Or remove/change quarkus.oidc.roles.source if roles should come from the ID token/access token instead.
  3. Or switch the tenant's application-type to web-app where UserInfo requirement is derived automatically if that is the intent.

Example fix

// before
quarkus.oidc.roles.source=userinfo

// after
quarkus.oidc.roles.source=userinfo
quarkus.oidc.authentication.user-info-required=true
Defensive patterns

Strategy: validation

Validate before calling

if ("userinfo".equals(config.getProperty("quarkus.oidc.roles.source"))
        && !"true".equals(config.getProperty("quarkus.oidc.authentication.user-info-required"))) {
    throw new IllegalStateException("roles.source=userinfo requires authentication.user-info-required=true");
}

Prevention

When it happens

Trigger: createTenantContext sees oidcConfig.roles().source() == Roles.Source.userinfo while enableUserInfo(oidcConfig) returns false — e.g. quarkus.oidc.roles.source=userinfo set without quarkus.oidc.authentication.user-info-required=true (and the tenant is not a web-app that implies UserInfo).

Common situations: Copy-pasting a roles.source=userinfo snippet without the matching user-info-required setting; changing application-type to service while keeping userinfo roles source; overriding user-info-required to false in a profile while roles.source stays userinfo.

Related errors


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