quarkusio/quarkus · error · ConfigurationException
Access token is required to check the roles but DefaultToken
Error message
Access token is required to check the roles but DefaultTokenStateManager is configured to not keep the access token
What it means
When roles are configured to be read from the access token (roles.source=accesstoken), the access token must be available. The DefaultTokenStateManager with the default strategy does not store the access token, so Quarkus throws this ConfigurationException when creating the tenant context.
Source
Thrown at extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/TenantContextFactory.java:328
throw new ConfigurationException(
"'" + getConfigPropertyForTenant(tenantId, "token.refresh-expired")
+ "' must be enabled to use '"
+ getConfigPropertyForTenant(tenantId, "token.refresh-token-cache-time-to-live")
+ "'");
}
}
if (oidcConfig.tokenStateManager()
.strategy() != io.quarkus.oidc.runtime.OidcTenantConfig.TokenStateManager.Strategy.KEEP_ALL_TOKENS) {
if (oidcConfig.authentication().userInfoRequired().orElse(false)
|| oidcConfig.roles().source()
.orElse(null) == io.quarkus.oidc.runtime.OidcTenantConfig.Roles.Source.userinfo) {
throw new ConfigurationException(
"UserInfo is required but DefaultTokenStateManager is configured to not keep the access token");
}
if (oidcConfig.roles().source().orElse(null) == io.quarkus.oidc.runtime.OidcTenantConfig.Roles.Source.accesstoken) {
throw new ConfigurationException(
"Access token is required to check the roles but DefaultTokenStateManager is configured to not keep the access token");
}
}
if (oidcConfig.token().verifyAccessTokenWithUserInfo().orElse(false)) {
if (!oidcConfig.discoveryEnabled().orElse(true)) {
if (oidcConfig.userInfoPath().isEmpty()) {
throw new ConfigurationException(
"UserInfo path is missing but 'verifyAccessTokenWithUserInfo' is enabled");
}
if (oidcConfig.introspectionPath().isPresent()) {
throw new ConfigurationException(
"Introspection path is configured and 'verifyAccessTokenWithUserInfo' is enabled, these options are mutually exclusive");
}
}
}
if (!oidcConfig.token().issuedAtRequired() && oidcConfig.token().age().isPresent()) {View on GitHub (pinned to e1c734241f)
Solutions
- Set quarkus.oidc.token-state-manager.strategy=keep-all-tokens
- Change roles.source (e.g. idtoken for web-apps) if access-token roles are not required
- Implement a custom TokenStateManager that persists the access token
Example fix
// before quarkus.oidc.roles.source=accesstoken quarkus.oidc.token-state-manager.strategy=keep-id-token // after quarkus.oidc.roles.source=accesstoken quarkus.oidc.token-state-manager.strategy=keep-all-tokens
Defensive patterns
Strategy: validation
Validate before calling
if (config.roles().source().orElse(null) == Roles.Source.accesstoken
&& config.tokenStateManager().strategy() != TokenStateManager.Strategy.KEEP_ALL_TOKENS) {
throw new IllegalArgumentException("strategy must be keep-all-tokens when roles.source=accesstoken");
} Type guard
boolean needsAccessToken(OidcTenantConfig c) {
return c.roles().source().orElse(null) == OidcTenantConfig.Roles.Source.accesstoken;
} Prevention
- Pair roles.source=accesstoken with strategy=keep-all-tokens
- Add a startup config smoke test for tenant settings
When it happens
Trigger: tokenStateManager().strategy() != KEEP_ALL_TOKENS and roles().source() == Source.accesstoken during createTenantContext.
Common situations: Setting quarkus.oidc.roles.source=accesstoken in a web-app where the strategy drops the access token from the session cookie; combining a slim token-state-manager strategy with access-token role checks.
Related errors
- The '%s' property can only be set to 'idtoken' for WEB_APP a
- UserInfo is not required but UserInfo is expected to be the
- '%s' must be enabled to use '%s'
- UserInfo is required but DefaultTokenStateManager is configu
- UserInfo path is missing but 'verifyAccessTokenWithUserInfo'
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/79ab12f6161d13bf.
Report an issue: GitHub.