dgraph-io/dgraph · error

the permission of ACL predicates can not be changed

Error message

the permission of ACL predicates can not be changed

What it means

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.

Source

Thrown at edgraph/access.go:817

	var groupIds []string
	// doAuthorizeMutation checks if modification of all the predicates are allowed
	// as a byproduct, it also sets the userId and groups
	doAuthorizeMutation := func() error {
		userData, err := extractUserAndGroups(ctx)
		if err != nil {
			// We don't follow fail open approach anymore.
			return status.Error(codes.Unauthenticated, err.Error())
		}

		userId = userData.userId
		groupIds = userData.groupIds

		if x.IsSuperAdmin(groupIds) {
			// Members of guardians group are allowed to mutate anything
			// (including delete) except the permission of the acl predicates.
			switch {
			case isAclPredMutation(gmu.Set):
				return errors.Errorf("the permission of ACL predicates can not be changed")
			case isAclPredMutation(gmu.Del):
				return errors.Errorf("ACL predicates can't be deleted")
			}
			if !shouldAllowAcls(userData.namespace) {
				for _, pred := range preds {
					if x.IsAclPredicate(pred) {
						return status.Errorf(codes.PermissionDenied,
							"unauthorized to mutate acl predicates: %s\n", pred)
					}
				}
			}
			return nil
		}
		result := authorizePreds(ctx, userData, preds, acl.Write)
		if len(result.blocked) > 0 {
			var msg strings.Builder
			for key := range result.blocked {
				x.Check2(msg.WriteString(key))

View on GitHub (pinned to 759e242be6)

Solutions

  1. Exclude ACL predicates from the mutation; use the `dgraph acl` CLI or ACL API to change permissions
  2. Filter out predicates starting with 'dgraph.' from your generated mutations
  3. Re-import only application data; let ACL bootstrap create its own predicates
  4. Use Move/Delete via ACL admin endpoints rather than raw mutations

Example fix

// before
mu.SetJson = allPredicatesJSON // includes dgraph.group.acl
// after
delete(allPredicatesJSON, "dgraph.group.acl") // or skip any pred with x.IsAclPredicate(pred)
mu.SetJson = filteredJSON
if err := dg.Mutate(ctx, mu); err != nil { /* ... */ }
Defensive patterns

Strategy: validation

Validate before calling

// Strip ACL predicates from mutation payloads
const ACL_PRED = /^dgraph\.(group\.acl|acl\.rule|pred)/
const safe = Object.fromEntries(
  Object.entries(mutationJson).filter(([pred]) => !ACL_PRED.test(pred))
)

Type guard

function isAclPredicate(pred) {
  return typeof pred === 'string' && pred.startsWith('dgraph.')
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01). Data as JSON: /api/errors/450631a75182f07e. Report an issue: GitHub.