{"record":{"id":"450631a75182f07e","repo":"dgraph-io/dgraph","slug":"the-permission-of-acl-predicates-can-not-be-change","errorCode":null,"errorMessage":"the permission of ACL predicates can not be changed","messagePattern":"the permission of ACL predicates can not be changed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"edgraph/access.go","lineNumber":817,"sourceCode":"\tvar groupIds []string\n\t// doAuthorizeMutation checks if modification of all the predicates are allowed\n\t// as a byproduct, it also sets the userId and groups\n\tdoAuthorizeMutation := func() error {\n\t\tuserData, err := extractUserAndGroups(ctx)\n\t\tif err != nil {\n\t\t\t// We don't follow fail open approach anymore.\n\t\t\treturn status.Error(codes.Unauthenticated, err.Error())\n\t\t}\n\n\t\tuserId = userData.userId\n\t\tgroupIds = userData.groupIds\n\n\t\tif x.IsSuperAdmin(groupIds) {\n\t\t\t// Members of guardians group are allowed to mutate anything\n\t\t\t// (including delete) except the permission of the acl predicates.\n\t\t\tswitch {\n\t\t\tcase isAclPredMutation(gmu.Set):\n\t\t\t\treturn errors.Errorf(\"the permission of ACL predicates can not be changed\")\n\t\t\tcase isAclPredMutation(gmu.Del):\n\t\t\t\treturn errors.Errorf(\"ACL predicates can't be deleted\")\n\t\t\t}\n\t\t\tif !shouldAllowAcls(userData.namespace) {\n\t\t\t\tfor _, pred := range preds {\n\t\t\t\t\tif x.IsAclPredicate(pred) {\n\t\t\t\t\t\treturn status.Errorf(codes.PermissionDenied,\n\t\t\t\t\t\t\t\"unauthorized to mutate acl predicates: %s\\n\", pred)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\t\tresult := authorizePreds(ctx, userData, preds, acl.Write)\n\t\tif len(result.blocked) > 0 {\n\t\t\tvar msg strings.Builder\n\t\t\tfor key := range result.blocked {\n\t\t\t\tx.Check2(msg.WriteString(key))","sourceCodeStart":799,"sourceCodeEnd":835,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/edgraph/access.go#L799-L835","documentation":"Guardians may mutate anything except the ACL permission predicates themselves; attempting a mutation that sets permission values on ACL predicates (dgraph.group.acl / dgraph.acl.rule style predicates) is blocked with this error to protect ACL integrity.","triggerScenarios":"A guardian user sends a mutation (Set) that includes predicates matched by isAclPredMutation — i.e. modifies the permission (dgraph.group.acl) predicate — via /mutate or Mutate RPC.","commonSituations":"Bulk data restores/migrations that try to write all predicates including ACL ones; scripts that copy entire datasets between namespaces; users trying to hand-edit group permissions via raw mutations instead of the ACL API.","solutions":["Exclude ACL predicates from the mutation; use the `dgraph acl` CLI or ACL API to change permissions","Filter out predicates starting with 'dgraph.' from your generated mutations","Re-import only application data; let ACL bootstrap create its own predicates","Use Move/Delete via ACL admin endpoints rather than raw mutations"],"exampleFix":"// before\nmu.SetJson = allPredicatesJSON // includes dgraph.group.acl\n// after\ndelete(allPredicatesJSON, \"dgraph.group.acl\") // or skip any pred with x.IsAclPredicate(pred)\nmu.SetJson = filteredJSON\nif err := dg.Mutate(ctx, mu); err != nil { /* ... */ }","handlingStrategy":"validation","validationCode":"// Strip ACL predicates from mutation payloads\nconst ACL_PRED = /^dgraph\\.(group\\.acl|acl\\.rule|pred)/\nconst safe = Object.fromEntries(\n  Object.entries(mutationJson).filter(([pred]) => !ACL_PRED.test(pred))\n)","typeGuard":"function isAclPredicate(pred) {\n  return typeof pred === 'string' && pred.startsWith('dgraph.')\n}","tryCatchPattern":null,"preventionTips":["Never include dgraph.* predicates in bulk data mutations","Use the `dgraph acl` CLI/API to change group permissions","When copying datasets, copy ACLs via ACL API, not raw mutations"],"tags":["acl","permission","mutation","guardians"],"backgroundTag":"acl-predicate-write-forbidden","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}