dgraph-io/dgraph · error

unable to parse ACLs: %v

Error message

unable to parse ACLs: %v

What it means

After successfully querying the old ACL data, upgradeACLRules expects a "rules" key in the result map holding the groups. If the response parses but lacks that key, the upgrade cannot interpret the ACL state and fails with this message, including the raw data for diagnosis.

Source

Thrown at upgrade/change_v20.03.0.go:50

type rule struct {
	Predicate  string `json:"predicate,omitempty"`
	Permission int    `json:"perm,omitempty"`
}

type rules []rule

func upgradeACLRules() error {
	dg, cb := x.GetDgraphClient(Upgrade.Conf, true)
	defer cb()

	data := make(map[string][]group)
	if err := getQueryResult(dg, queryACLGroupsBefore_v20_03_0, &data); err != nil {
		return fmt.Errorf("error querying old ACL rules: %w", err)
	}

	groups, ok := data["rules"]
	if !ok {
		return fmt.Errorf("unable to parse ACLs: %v", data)
	}

	counter := 1
	var nquads []*api.NQuad
	for _, group := range groups {
		if group.ACL == "" {
			continue
		}

		var rs rules
		if err := json.Unmarshal([]byte(group.ACL), &rs); err != nil {
			return fmt.Errorf("unable to unmarshal ACL: %v :: %w", group.ACL, err)
		}

		for _, r := range rs {
			newRuleStr := fmt.Sprintf("_:newrule%d", counter)
			nquads = append(nquads, []*api.NQuad{
				// the name of the type was Rule in v20.03.0

View on GitHub (pinned to 759e242be6)

Solutions

  1. Confirm the cluster actually used the v20.03.0 ACL format (dgraph.group.acl predicate) before running the upgrade
  2. If ACLs were never enabled or were already migrated, skip this upgrade step — nothing to do
  3. Inspect the printed data map to see what the query actually returned
  4. Re-run against a backup/snapshot of the pre-upgrade cluster if the old ACLs must be recovered
Defensive patterns

Strategy: fallback

Validate before calling

// pre-check whether old ACL data exists at all
out, _ := exec.Command("curl", "-s", "alpha:8080/query", "-d", `{q(func: has(dgraph.group.acl)){dgraph.group.acl}}`).Output()
if !strings.Contains(string(out), "dgraph.group.acl") {
    fmt.Println("no old ACLs; skipping upgrade step")
    return nil
}

Try / catch

if err := upgradeACLRules(); err != nil {
    if strings.Contains(err.Error(), "unable to parse ACLs") {
        // likely no old-format data or already migrated; treat as no-op
        return nil
    }
    return err
}

Prevention

When it happens

Trigger: The query returned a result whose top-level map has no "rules" entry — e.g. the cluster has no dgraph.group.acl data at all, or the response shape differs because the cluster is already on a newer schema version.

Common situations: Running the 20.03 upgrade against a cluster that never had ACLs enabled; running it twice (second run finds no old-format data); running against a newer cluster where ACLs were stored in the new format already.

Understand the failure class

Related errors


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