quarkusio/quarkus · error · ConfigurationException
'%s' must be enabled to use '%s'
Error message
'%s' must be enabled to use '%s'
What it means
token.refresh-token-cache-time-to-live controls caching of refreshed tokens, which only exists when token.refresh-expired=true is set. Quarkus OIDC validates this dependency when building the tenant context and throws a ConfigurationException if the cache TTL is set while refresh is disabled.
Source
Thrown at extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/TenantContextFactory.java:310
&& oidcConfig.roles().source().get() == io.quarkus.oidc.runtime.OidcTenantConfig.Roles.Source.idtoken) {
throw new ConfigurationException(
"The '" + getConfigPropertyForTenant(tenantId, "roles.source")
+ "' property can only be set to 'idtoken' for "
+ io.quarkus.oidc.runtime.OidcTenantConfig.ApplicationType.WEB_APP
+ " application types");
}
} else {
if (oidcConfig.token().refreshTokenTimeSkew().isPresent()) {
oidcConfig.token.setRefreshExpired(true);
}
if (oidcConfig.authentication().sessionAgeExtension().isPresent()
&& !oidcConfig.token().refreshExpired()) {
LOG.warn(
"Session age extension will not be effective because 'quarkus.oidc.token.refresh-expired=true' is not set");
}
if (!oidcConfig.token().refreshExpired()
&& !oidcConfig.token().refreshTokenCacheTimeToLive().isZero()) {
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(View on GitHub (pinned to e1c734241f)
Solutions
- Set quarkus.oidc.token.refresh-expired=true if token refresh with caching is intended
- Remove/quarkus.oidc.token.refresh-token-cache-time-to-live (leave it at PT0S) if refresh is not used
- Check per-tenant overrides: quarkus.oidc.<tenant>.token.refresh-token-cache-time-to-live
Example fix
// before quarkus.oidc.token.refresh-token-cache-time-to-live=1H // after quarkus.oidc.token.refresh-expired=true quarkus.oidc.token.refresh-token-cache-time-to-live=1H
Defensive patterns
Strategy: validation
Validate before calling
if (!config.token().refreshExpired() && !config.token().refreshTokenCacheTimeToLive().isZero()) {
throw new IllegalArgumentException("refresh-token-cache-time-to-live requires token.refresh-expired=true");
} Prevention
- Set refresh-expired=true before any refresh-cache tuning
- Review token.* properties as a group when editing tenant config
When it happens
Trigger: oidcConfig.token().refreshExpired() is false and token().refreshTokenCacheTimeToLive() is non-zero during createTenantContext (web-app branch of validation).
Common situations: Setting quarkus.oidc.token.refresh-token-cache-time-to-live without also setting refresh-expired=true; inheriting a default/typed OidcTenantConfig where a non-zero TTL was set programmatically; copy-pasting token config across tenants.
Related errors
- The '%s' property can only be enabled for WEB_APP applicatio
- The '%s' property can only be set to 'idtoken' for WEB_APP a
- UserInfo is required but DefaultTokenStateManager is configu
- Access token is required to check the roles but DefaultToken
- UserInfo path is missing but 'verifyAccessTokenWithUserInfo'
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/852c651439a0270d.
Report an issue: GitHub.