dgraph-io/dgraph · critical
Multiple groot users found
Error message
Multiple groot users found
What it means
upsertGroot looks up the 'groot' super-admin user in Dgraph. When the query returns zero or more than one groot user (the source only assigns a uid in the ==1 case), it wraps the underlying error with 'Multiple groot users found'. It indicates corrupted or duplicated ACL state in the stored data.
Source
Thrown at edgraph/access.go:590
type userQryResp struct {
GrootUser []userNode `json:"grootUser"`
}
var grootUserUid string
var userResp userQryResp
if err := json.Unmarshal(resp.GetJson(), &userResp); err != nil {
return errors.Wrap(err, "Couldn't unmarshal response from groot user query")
}
if len(userResp.GrootUser) == 0 {
// no groot user found from query
// Extract uid of created groot user from mutation
newUserUidMap := resp.GetUids()
grootUserUid = newUserUidMap["newuser"]
} else if len(userResp.GrootUser) == 1 {
// we found a groot user
grootUserUid = userResp.GrootUser[0].Uid
} else {
return errors.Wrap(err, "Multiple groot users found")
}
uid, err := strconv.ParseUint(grootUserUid, 0, 64)
if err != nil {
return errors.Wrapf(err, "Error while parsing Uid: %s of groot user", grootUserUid)
}
ns, err := x.ExtractNamespace(ctx)
if err != nil {
return errors.Wrapf(err, "While upserting user with id %s", x.GrootId)
}
x.GrootUid.Store(ns, uid)
glog.V(2).Infof("Successfully upserted groot account for namespace %d\n", ns)
return nil
}
// extract the userId, groupIds from the accessJwt in the context
func extractUserAndGroups(ctx context.Context) (*userData, error) {
accessJwt, err := x.ExtractJwt(ctx)View on GitHub (pinned to 759e242be6)
Solutions
- Inspect the groot user records with a query and delete duplicates so exactly one 'groot' user exists, or recreate the ACL dataset from scratch
- Re-bootstrap ACLs on a clean cluster (start with --acl and a fresh Galaxy key) so upsertGroot creates the single groot account
- If groot is missing entirely, check earlier errors in upsertGuardianAndGroot (the wrapped err) — the user creation step likely failed
- Disable ACL (--acl=false) only as a diagnostic, not a fix, if you don't need ACLs
Example fix
// before: multiple groot users in DB -> error
// after: ensure exactly one groot user via query in Ratel:
// query { me(func: eq(dgraph.xid, "groot")) { uid } }
// delete extra nodes:
// upsert { query {...} delete { uid <extra> * * . } }
// then restart with ACL enabled so groot is upserted once Defensive patterns
Strategy: validation
Validate before calling
// Before relying on ACL bootstrap, verify exactly one groot user exists:
const q = `{ me(func: eq(dgraph.xid, "groot")) { uid } }`
const res = await dg.newTxn().query(q)
const users = res.data.me
if (users.length !== 1) {
// clean up duplicates or re-bootstrap ACLs before proceeding
throw new Error(`expected 1 groot user, found ${users.length}`)
} Type guard
function hasSingleGroot(res) {
return Array.isArray(res?.data?.me) && res.data.me.length === 1 && typeof res.data.me[0].uid === 'string'
} Prevention
- Never hand-edit ACL data (dgraph.xid nodes) in Ratel
- After restores/imports, always re-run or verify ACL bootstrap
- Alert on any query returning more than one node with dgraph.xid == 'groot'
When it happens
Trigger: Calling Reset, or any first-boot path that runs upsertGuardianAndGroot/createGuardianAndGroot, when the gql query for user 'groot' returns len(GrootUser) != 1 (0 or >1 matches) — e.g. multiple groot accounts exist in the namespace, or the groot user was never created because ACL bootstrap failed.
Common situations: Corrupted or manually-edited ACL data; importing data without the ACL schema/records; multi-namespace setups where groot was upserted more than once; running ACL-enabled Dgraph on a dataset bootstrapped without ACLs.
Related errors
- Error while parsing Uid: %s of groot user
- error querying old ACL rules: %w
- unable to parse ACLs: %v
- unable to unmarshal ACL: %v :: %w
- error upgrading ACL rules: %w
AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01).
Data as JSON: /api/errors/ef2286700c9cb18a.
Report an issue: GitHub.