dgraph-io/dgraph · error
I am not the Zero leader
Error message
I am not the Zero leader
What it means
movePredicate must run on the current Zero leader because it must propose the final tablet reassignment through the Zero raft group. After refreshing membership it checks s.Node.AmLeader(); if this Zero is a follower, it refuses with this error. Note MoveTablet checks leadership earlier too, but the rebalancer path (and a leadership change mid-request) can hit this inside movePredicate.
Source
Thrown at dgraph/cmd/zero/tablet.go:174
// whose moves keep failing.
start := time.Now()
defer func() {
s.recordMoveResult(predicate, time.Since(start), err)
}()
timeout := moveTimeout(predicateMoveTimeout, tab)
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
span := trace.SpanFromContext(ctx)
defer span.End()
// Ensure that I'm connected to the rest of the Zero group, and am the leader.
if _, err := s.latestMembershipState(ctx); err != nil {
return errors.Wrapf(err, "unable to reach quorum")
}
if !s.Node.AmLeader() {
return errors.Errorf("I am not the Zero leader")
}
msg := fmt.Sprintf("Going to move predicate: [%v], size: [ondisk: %v, uncompressed: %v]"+
" from group %d to %d, timeout: %v\n", predicate, humanize.IBytes(uint64(tab.OnDiskBytes)),
humanize.IBytes(uint64(tab.UncompressedBytes)), srcGroup, dstGroup, timeout)
glog.Info(msg)
span.SetAttributes(attribute.String("tablet", predicate))
span.SetStatus(1, msg)
// Block all commits on this predicate. Keep them blocked until we return from this function.
unblock := s.blockTablet(predicate)
defer unblock()
// Get a new timestamp, beyond which we are sure that no new txns would be committed for this
// predicate. Source Alpha leader must reach this timestamp before streaming the data.
ids, err := s.Timestamps(ctx, &pb.Num{Val: 1})
if err != nil || ids.StartId == 0 {
return errors.Wrapf(err, "while leasing txn timestamp. Id: %+v", ids)
}View on GitHub (pinned to 759e242be6)
Solutions
- Find the current Zero leader via /state and send the move request to it
- Configure the load balancer/proxy to route Zero writes to the leader only
- Wait for leadership to stabilize (check Zero logs for raft elections) and retry
- Investigate frequent leadership changes if this recurs — often network or disk latency between Zeros
Example fix
// before curl 'zero-follower:6080/moveTablet?tablet=name&dst_group=2' // after LEADER=$(curl -s zero-follower:6080/state | jq -r '.leader // .max_leason_id' ) curl "zero-leader:6080/moveTablet?tablet=name&dst_group=2"
Defensive patterns
Strategy: retry
Validate before calling
# resolve current Zero leader and target it
leader=$(curl -s localhost:6080/state | jq -r '.leader // empty')
[ -n "$leader" ] || { echo "no zero leader elected"; exit 1; } Try / catch
resp=$(curl -s "localhost:6080/moveTablet?tablet=$TABLET&dst_group=$DST") if [[ "$(echo "$resp" | jq -r .msg)" == *"not the Zero leader"* ]]; then leader=$(curl -s localhost:6080/state | jq -r '.leader') resp=$(curl -s "http://$leader/moveTablet?tablet=$TABLET&dst_group=$DST") fi
Prevention
- Always resolve the current Zero leader from /state before issuing moves
- Point a dedicated admin port/proxy at the leader only
- Investigate frequent Zero leader elections (network/disk latency) if this recurs
- Retry quickly — a new leader is usually elected within seconds
When it happens
Trigger: The move was issued to (or rebalancer runs on) a Zero follower; Zero leadership changed after the request was accepted; multiple Zeros with stale views where a follower still believes it leads.
Common situations: Load balancer routing the /moveTablet HTTP call to any Zero instead of only the leader; scripted moves hard-coding a non-leader Zero address; leadership flapping due to unstable network between Zeros.
Related errors
- group: [%d] is not a known group
- namespace: %d. No tablet found for: %s
- namespace: %d. Tablet: [%s] is already being served by group
- Unable to move reserved predicate %s
- Tablet to be moved: [%v] is not being served
AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01).
Data as JSON: /api/errors/c9c49ee0ccbbe579.
Report an issue: GitHub.