{"record":{"id":"8707e872a53aaf60","repo":"quarkusio/quarkus","slug":"userinfo-is-required-but-s-is-not-configured","errorCode":null,"errorMessage":"UserInfo is required but '%s' is not configured.","messagePattern":"UserInfo is required but '(.+?)' is not configured\\.","errorType":"validation","errorClass":"ConfigurationException","httpStatus":null,"severity":"error","filePath":"extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/TenantContextFactory.java","lineNumber":265,"sourceCode":"                                    + \"' properties \"\n                                    + \"set when the discovery is disabled.\",\n                            Set.of(authorizationPathProperty, tokenPathProperty));\n                }\n            }\n            // JWK and introspection endpoints have to be set for both 'web-app' and 'service' applications\n            if (oidcConfig.jwksPath().isEmpty() && oidcConfig.introspectionPath().isEmpty()) {\n                if (!oidcConfig.authentication().idTokenRequired().orElse(true)\n                        && 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","sourceCodeStart":247,"sourceCodeEnd":283,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/TenantContextFactory.java#L247-L283","documentation":"When UserInfo is required (quarkus.oidc.authentication.user-info-required=true) but discovery is disabled, Quarkus must be told explicitly where the UserInfo endpoint is. createTenantContext throws this ConfigurationException when userInfoRequired is true and user-info-path is empty, naming the expected property (quarkus.oidc.user-info-path or its tenant-scoped form).","triggerScenarios":"createTenantContext finds oidcConfig.authentication().userInfoRequired() == true, oidcConfig.userInfoPath().isEmpty(), and discoveryEnabled() == false — i.e. user-info-required=true with quarkus.oidc.discovery-enabled=false and no quarkus.oidc.user-info-path.","commonSituations":"Adding user-info-required=true to a tenant whose config already had discovery disabled; IdP lacks the well-known endpoint and user-info-path was never set; profile merges that turned discovery off while keeping user-info-required.","solutions":["Set quarkus.oidc.user-info-path (e.g. /protocol/openid-connect/userinfo) for the tenant.","Or re-enable discovery (quarkus.oidc.discovery-enabled=true) if the provider publishes the well-known config.","Or remove quarkus.oidc.authentication.user-info-required=true if UserInfo is not actually needed."],"exampleFix":"// before\nquarkus.oidc.discovery-enabled=false\nquarkus.oidc.authentication.user-info-required=true\n\n// after\nquarkus.oidc.discovery-enabled=false\nquarkus.oidc.authentication.user-info-required=true\nquarkus.oidc.user-info-path=/protocol/openid-connect/userinfo","handlingStrategy":"validation","validationCode":"boolean userInfoRequired = \"true\".equals(config.getProperty(\"quarkus.oidc.authentication.user-info-required\"));\nboolean discoveryDisabled = \"false\".equals(config.getProperty(\"quarkus.oidc.discovery-enabled\"));\nif (userInfoRequired && discoveryDisabled && config.getProperty(\"quarkus.oidc.user-info-path\") == null) {\n    throw new IllegalStateException(\"user-info-path is required when user-info-required=true and discovery is disabled\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pair user-info-required=true with an explicit user-info-path whenever discovery is disabled.","Check provider docs for the correct userinfo endpoint path.","Run a config audit when toggling discovery-enabled."],"tags":["oidc","configuration","userinfo","discovery","startup"],"backgroundTag":"missing-required-config-property","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}