{"record":{"id":"c9c49ee0ccbbe579","repo":"dgraph-io/dgraph","slug":"i-am-not-the-zero-leader","errorCode":null,"errorMessage":"I am not the Zero leader","messagePattern":"I am not the Zero leader","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"dgraph/cmd/zero/tablet.go","lineNumber":174,"sourceCode":"\t// whose moves keep failing.\n\tstart := time.Now()\n\tdefer func() {\n\t\ts.recordMoveResult(predicate, time.Since(start), err)\n\t}()\n\n\ttimeout := moveTimeout(predicateMoveTimeout, tab)\n\tctx, cancel := context.WithTimeout(context.Background(), timeout)\n\tdefer cancel()\n\n\tspan := trace.SpanFromContext(ctx)\n\tdefer span.End()\n\n\t// Ensure that I'm connected to the rest of the Zero group, and am the leader.\n\tif _, err := s.latestMembershipState(ctx); err != nil {\n\t\treturn errors.Wrapf(err, \"unable to reach quorum\")\n\t}\n\tif !s.Node.AmLeader() {\n\t\treturn errors.Errorf(\"I am not the Zero leader\")\n\t}\n\tmsg := fmt.Sprintf(\"Going to move predicate: [%v], size: [ondisk: %v, uncompressed: %v]\"+\n\t\t\" from group %d to %d, timeout: %v\\n\", predicate, humanize.IBytes(uint64(tab.OnDiskBytes)),\n\t\thumanize.IBytes(uint64(tab.UncompressedBytes)), srcGroup, dstGroup, timeout)\n\tglog.Info(msg)\n\tspan.SetAttributes(attribute.String(\"tablet\", predicate))\n\tspan.SetStatus(1, msg)\n\n\t// Block all commits on this predicate. Keep them blocked until we return from this function.\n\tunblock := s.blockTablet(predicate)\n\tdefer unblock()\n\n\t// Get a new timestamp, beyond which we are sure that no new txns would be committed for this\n\t// predicate. Source Alpha leader must reach this timestamp before streaming the data.\n\tids, err := s.Timestamps(ctx, &pb.Num{Val: 1})\n\tif err != nil || ids.StartId == 0 {\n\t\treturn errors.Wrapf(err, \"while leasing txn timestamp. Id: %+v\", ids)\n\t}","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/dgraph/cmd/zero/tablet.go#L156-L192","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\ncurl 'zero-follower:6080/moveTablet?tablet=name&dst_group=2'\n// after\nLEADER=$(curl -s zero-follower:6080/state | jq -r '.leader // .max_leason_id' )\ncurl \"zero-leader:6080/moveTablet?tablet=name&dst_group=2\"","handlingStrategy":"retry","validationCode":"# resolve current Zero leader and target it\nleader=$(curl -s localhost:6080/state | jq -r '.leader // empty')\n[ -n \"$leader\" ] || { echo \"no zero leader elected\"; exit 1; }","typeGuard":null,"tryCatchPattern":"resp=$(curl -s \"localhost:6080/moveTablet?tablet=$TABLET&dst_group=$DST\")\nif [[ \"$(echo \"$resp\" | jq -r .msg)\" == *\"not the Zero leader\"* ]]; then\n  leader=$(curl -s localhost:6080/state | jq -r '.leader')\n  resp=$(curl -s \"http://$leader/moveTablet?tablet=$TABLET&dst_group=$DST\")\nfi","preventionTips":["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"],"tags":["dgraph","zero","leader","raft","tablet"],"backgroundTag":"not-leader","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}