{"record":{"id":"e0901d0717743540","repo":"weaviate/weaviate","slug":"namespaces-enabled-false-but-cluster-has-d-namesp-e0901d","errorCode":null,"errorMessage":"NAMESPACES_ENABLED=false but cluster has %d namespace-qualified role permission(s) (e.g. %q); refusing to start with inconsistent state","messagePattern":"NAMESPACES_ENABLED=false but cluster has (.+?) namespace-qualified role permission\\(s\\) \\(e\\.g\\. %q\\); refusing to start with inconsistent state","errorType":"console","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"adapters/handlers/rest/configure_api.go","lineNumber":1317,"sourceCode":"\t\t// Guards against disabling namespaces on a namespaced cluster.\n\t\treturn fmt.Errorf(\"NAMESPACES_ENABLED=false but cluster has %d namespace-qualified collection(s) (e.g. %q); refusing to start with inconsistent state\", namespacedCount, namespacedExample)\n\t}\n\n\t// Role names, policy resources (what a role's permissions grant access to)\n\t// and grouping subjects (who a role assignment binds) may each be\n\t// namespace-qualified when NAMESPACES_ENABLED=true. With namespaces disabled\n\t// they would be misinterpreted, so the rows are only inspected in that case.\n\tif !enabled {\n\t\tif n, ex := countQualified(roleNames, conv.ContainsNamespaceSeparator); n > 0 {\n\t\t\treturn fmt.Errorf(\"NAMESPACES_ENABLED=false but cluster has %d namespace-qualified role(s) (e.g. %q); refusing to start with inconsistent state\", n, ex)\n\t\t}\n\t\t// A users/<id> or groups/<type>/<name> resource may carry a ':' inside the\n\t\t// id itself (e.g. an OIDC username), so its colon is not a namespace\n\t\t// qualifier and the resource is skipped; collection/role shapes still count.\n\t\tif n, ex := countQualified(policyResources, func(r string) bool {\n\t\t\treturn !conv.IsOpaqueIDResource(r) && conv.ContainsNamespaceSeparator(r)\n\t\t}); n > 0 {\n\t\t\treturn fmt.Errorf(\"NAMESPACES_ENABLED=false but cluster has %d namespace-qualified role permission(s) (e.g. %q); refusing to start with inconsistent state\", n, ex)\n\t\t}\n\t\t// Only a colon in a direct db user (e.g. db:customer1:alice) is a namespace\n\t\t// qualifier — db names forbid ':'. OIDC names may contain ':', so oidc:\n\t\t// subjects are ambiguous and skipped; groups are global regardless of name.\n\t\tif n, ex := countQualified(groupingSubjects, func(s string) bool {\n\t\t\tuser, prefix, err := conv.GetUserAndPrefix(s)\n\t\t\tif err != nil || prefix != string(authentication.AuthTypeDb) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\treturn conv.ContainsNamespaceSeparator(user)\n\t\t}); n > 0 {\n\t\t\treturn fmt.Errorf(\"NAMESPACES_ENABLED=false but cluster has %d role assignment(s) to a namespace-qualified principal (e.g. %q); refusing to start with inconsistent state\", n, ex)\n\t\t}\n\t}\n\treturn nil\n}\n\n// countQualified returns how many values satisfy isQualified and the first such","sourceCodeStart":1299,"sourceCodeEnd":1335,"githubUrl":"https://github.com/weaviate/weaviate/blob/75aa4b6d11f8818305aafd4440b4e32794f7ca04/adapters/handlers/rest/configure_api.go#L1299-L1335","documentation":"With NAMESPACES_ENABLED=false, the startup check inspects stored policy resources (what role permissions grant access to) and aborts if any contain a namespace qualifier ':' — except opaque ID resources like users/<id> or groups/<type>/<name>, whose colons may belong to the ID itself and are deliberately skipped. The guard exists because qualified permission resources would be misinterpreted with namespaces off.","triggerScenarios":"Boot with NAMESPACES_ENABLED=false while the RBAC store holds permissions targeting namespace-qualified resources (e.g. collections like 'ns1:Article'); opaque-ID resources are ignored, plain qualified resources trigger the error.","commonSituations":"Rolling back NAMESPACES_ENABLED after permissions were granted against namespaced collections; restoring a namespaced RBAC backup onto a non-namespaced node; copying authorization state between differently configured clusters.","solutions":["Restart with NAMESPACES_ENABLED=true to interpret the qualified permission resources.","Revoke or rewrite the offending role permissions (remove 'ns:'-qualified resources) while namespaces are enabled, then boot with the flag off.","Start from a clean meta-store if the permissions are disposable."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// scan policy resources for namespace qualifiers, skipping opaque IDs (users/<id>, groups/<type>/<name>)\nfor _, res := range listPolicyResources() {\n  if isOpaqueIDResource(res) { continue }\n  if strings.Contains(res, \":\") {\n    return fmt.Errorf(\"permission resource %q is namespace-qualified; keep NAMESPACES_ENABLED=true\", res)\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Revoke/re-grant permissions against non-qualified resources before disabling namespaces.","Snapshot RBAC state before flag changes so you can roll back cleanly.","Keep authorization data within a single cluster's namespace configuration."],"tags":["startup","rbac","permissions","namespaces"],"backgroundTag":"namespaces-flag-cluster-state-mismatch","analyzedSha":"75aa4b6d11f8818305aafd4440b4e32794f7ca04","analyzedAt":"2026-09-04T14:58:20.392Z","contentChangedAt":"2026-09-04T14:58:20.392Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}