dgraph-io/dgraph · error

While upserting user with id %s

Error message

While upserting user with id %s

What it means

upsertGroot extracts the namespace from the request context via x.ExtractNamespace(ctx) and wraps any failure with 'While upserting user with id %s' (id = x.GrootId). The namespace header (AccessJwt-Namespace) is missing or malformed in the internal context used for groot upsert.

Source

Thrown at edgraph/access.go:599

	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)
	if err != nil {
		return nil, err
	}
	return validateToken(accessJwt)
}

type authPredResult struct {
	allowed []string
	blocked map[string]struct{}

View on GitHub (pinned to 759e242be6)

Solutions

  1. Ensure the client sends the correct AccessJwt-Namespace (or use a current dgraph client that does)
  2. Use the superadmin namespace (0) for groot/guardian operations
  3. Upgrade the dgraph Go client/grpclient if it predates namespace support
  4. Check that a proxy (e.g. nginx/grpc-web) isn't dropping metadata headers

Example fix

// before
conn, _ := grpc.Dial(addr)
c := api.NewDgraphClient(conn)
c.Reset(ctx)
// after
ctx = metadata.AppendToOutgoingContext(ctx, "AccessJwt-Namespace", "0")
c.Reset(ctx)
Defensive patterns

Strategy: validation

Validate before calling

// Attach namespace metadata before any admin/ACL call
import { Metadata } from '@grpc/grpc-js'
const md = new Metadata()
md.add('AccessJwt-Namespace', String(namespace)) // e.g. '0' for superadmin
if (!namespace || isNaN(Number(namespace))) {
  throw new Error('valid namespace required for groot operations')
}

Type guard

function hasNamespace(ctx) {
  return ctx != null && Number.isInteger(Number(ctx.namespace))
}

Prevention

When it happens

Trigger: Calling any ACL bootstrapping/admin operation whose context lacks a valid namespace value — e.g. health checking, Reset, or Guardian operations issued without the namespace header or with a malformed one.

Common situations: Client/proxy stripping the AccessJwt-Namespace header; connecting with an old client SDK that doesn't send namespace info; calling admin endpoints cross-namespace.

Related errors


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