{"record":{"id":"edf989b420475431","repo":"quarkusio/quarkus","slug":"the-s-property-can-only-be-enabled-for-web-app","errorCode":null,"errorMessage":"The '%s' property can only be enabled for WEB_APP application types","messagePattern":"The '(.+?)' property can only be enabled for WEB_APP application types","errorType":"validation","errorClass":"ConfigurationException","httpStatus":null,"severity":"error","filePath":"extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/TenantContextFactory.java","lineNumber":273,"sourceCode":"                        && oidcConfig.authentication().userInfoRequired().orElse(false)) {\n                    LOG.debugf(\"tenant %s supports only UserInfo\", oidcConfig.tenantId().get());\n                } else if (OidcUtils.isServiceApp(oidcConfig)) {\n                    throw new ConfigurationException(\n                            \"Either 'jwks-path' or 'introspection-path' properties must be set when the discovery is disabled.\",\n                            Set.of(\"quarkus.oidc.jwks-path\", \"quarkus.oidc.introspection-path\"));\n                }\n            }\n            if (oidcConfig.authentication().userInfoRequired().orElse(false) && oidcConfig.userInfoPath().isEmpty()) {\n                String configProperty = getConfigPropertyForTenant(tenantId, \"user-info-path\");\n                throw new ConfigurationException(\n                        \"UserInfo is required but '\" + configProperty + \"' is not configured.\",\n                        Set.of(configProperty));\n            }\n        }\n\n        if (OidcUtils.isServiceApp(oidcConfig)) {\n            if (oidcConfig.token().refreshExpired()) {\n                throw new ConfigurationException(\n                        \"The '\" + getConfigPropertyForTenant(tenantId, \"token.refresh-expired\")\n                                + \"' property can only be enabled for \"\n                                + io.quarkus.oidc.runtime.OidcTenantConfig.ApplicationType.WEB_APP\n                                + \" application types\");\n            }\n            if (oidcConfig.token().refreshTokenTimeSkew().isPresent()) {\n                throw new ConfigurationException(\n                        \"The '\" + getConfigPropertyForTenant(tenantId, \"token.refresh-token-time-skew\")\n                                + \"' property can only be enabled for \"\n                                + io.quarkus.oidc.runtime.OidcTenantConfig.ApplicationType.WEB_APP\n                                + \" application types\");\n            }\n            if (oidcConfig.logout().path().isPresent()) {\n                throw new ConfigurationException(\n                        \"The '\" + getConfigPropertyForTenant(tenantId, \"logout.path\") + \"' property can only be enabled for \"\n                                + io.quarkus.oidc.runtime.OidcTenantConfig.ApplicationType.WEB_APP + \" application types\");\n            }\n            if (oidcConfig.roles().source().isPresent()","sourceCodeStart":255,"sourceCodeEnd":291,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/TenantContextFactory.java#L255-L291","documentation":"Refreshing expired access tokens requires an authenticated browser session with a refresh token, which only exists for code-flow (WEB_APP) applications. Bearer-token (service) applications have no refresh token, so quarkus.oidc.token.refresh-expired (or a provided refresh-token-time-skew) is invalid there. createTenantContext throws this ConfigurationException for service apps with refresh-enabled settings.","triggerScenarios":"createTenantContext finds OidcUtils.isServiceApp(oidcConfig) == true and either oidcConfig.token().refreshExpired() is true (quarkus.oidc.token.refresh-expired=true) or oidcConfig.token().refreshTokenTimeSkew().isPresent(), on a service application type tenant.","commonSituations":"Setting application-type=service (or leaving the default when only bearer tokens are used) while copying web-app token settings; enabling refresh-expired globally in quarkus.oidc.* while the app is a service app; a shared base config enabling refresh for all tenants.","solutions":["Remove quarkus.oidc.token.refresh-expired=true (and token.refresh-token-time-skew) from service tenants.","Or set quarkus.oidc.application-type=web-app if the application really performs code flow and holds refresh tokens.","Or move the refresh settings to a tenant-specific scope (quarkus.oidc.<tenant>.token.refresh-expired) used only by web-app tenants."],"exampleFix":"// before\nquarkus.oidc.application-type=service\nquarkus.oidc.token.refresh-expired=true\n\n// after\nquarkus.oidc.application-type=service\nquarkus.oidc.token.refresh-expired=false","handlingStrategy":"validation","validationCode":"String appType = config.getProperty(\"quarkus.oidc.application-type\");\nboolean refreshEnabled = \"true\".equals(config.getProperty(\"quarkus.oidc.token.refresh-expired\"));\nif (refreshEnabled && (appType == null || appType.equals(\"service\"))) {\n    throw new IllegalStateException(\"token.refresh-expired is only valid for application-type=web-app\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Enable token refresh only in web-app tenant blocks.","Remember refresh requires a refresh token, which only code flow provides.","Review global quarkus.oidc.* settings that implicitly apply to service tenants.","Re-check token options whenever application-type changes."],"tags":["oidc","configuration","token-refresh","application-type","startup"],"backgroundTag":"incompatible-oidc-app-type-config","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}