{"record":{"id":"0f200bea74ee467a","repo":"dgraph-io/dgraph","slug":"acl-predicates-can-t-be-deleted","errorCode":null,"errorMessage":"ACL predicates can't be deleted","messagePattern":"ACL predicates can't be deleted","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"edgraph/access.go","lineNumber":819,"sourceCode":"\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))\n\t\t\t\tx.Check2(msg.WriteString(\" \"))\n\t\t\t}","sourceCodeStart":801,"sourceCodeEnd":837,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/edgraph/access.go#L801-L837","documentation":"Error returned by the ACL layer in edgraph/access.go when a mutation attempts to delete predicates that are reserved for access control (e.g. dgraph.xid, dgraph.password, dgraph.user.group or other ACL-internal predicates). Fix by excluding ACL predicates from the deletion.","triggerScenarios":"A guardian sends a Del mutation whose predicates include ACL permission predicates (matched by isAclPredMutation(gmu.Del)), e.g. dropping nodes with wildcard predicate deletion that sweeps in dgraph.group.acl.","commonSituations":"Drop-by-uid wildcard deletes (`S * * .`) that unintentionally include ACL predicates; cleanup scripts purging all data for a namespace; copying delete logic from non-ACL clusters.","solutions":["Narrow delete patterns to exclude ACL predicates (avoid `* * .` wildcards on ACL-owned nodes)","Use `dgraph acl` CLI to manage/remove ACL rules instead of raw delete mutations","List the exact predicates you intend to delete and verify none match x.IsAclPredicate","For full resets, use DropAll as a guardian rather than targeted deletes"],"exampleFix":"// before\ndel.Nquads = []string{fmt.Sprintf(\"<%s> * * .\", uid)} // can hit ACL preds\n// after\ndel.Nquads = []string{fmt.Sprintf(\"<%s> <app.pred1> * .\", uid), fmt.Sprintf(\"<%s> <app.pred2> * .\", uid)}","handlingStrategy":"validation","validationCode":"// Expand wildcard deletes explicitly and filter ACL predicates\nconst targets = ['app.pred1', 'app.pred2']\nif (targets.some(p => p.startsWith('dgraph.'))) {\n  throw new Error('refusing to delete ACL predicates')\n}","typeGuard":"function isSafeDelete(preds) {\n  return preds.every(p => !String(p).startsWith('dgraph.'))\n}","tryCatchPattern":"try {\n  await dg.mutate(delMutation)\n} catch (e) {\n  if (/ACL predicates can't be deleted/.test(e.message)) {\n    // rewrite mutation without dgraph.* predicates and retry once\n  }\n  throw e\n}","preventionTips":["Avoid `S * * .` wildcard deletes on nodes that may own ACL predicates","Keep ACL rule management exclusively in `dgraph acl` workflows","Review generated N-Quads in tests for any dgraph.* predicate writes"],"tags":["acl","delete","permission","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"}