{"record":{"id":"66d7cdff855c30e2","repo":"dgraph-io/dgraph","slug":"while-proposing-tablet-reassignment-proposal-v","errorCode":null,"errorMessage":"while proposing tablet reassignment. Proposal: %+v","messagePattern":"while proposing tablet reassignment\\. Proposal: %\\+v","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"dgraph/cmd/zero/tablet.go","lineNumber":225,"sourceCode":"\tglog.Infof(\"Starting move: %+v\", in)\n\tif _, err := wc.MovePredicate(ctx, in); err != nil {\n\t\treturn errors.Wrapf(err, \"while calling MovePredicate\")\n\t}\n\n\tp := &pb.ZeroProposal{}\n\tp.Tablet = &pb.Tablet{\n\t\tGroupId:           dstGroup,\n\t\tPredicate:         predicate,\n\t\tOnDiskBytes:       tab.OnDiskBytes,\n\t\tUncompressedBytes: tab.UncompressedBytes,\n\t\tForce:             true,\n\t\tMoveTs:            in.TxnTs,\n\t}\n\tmsg = fmt.Sprintf(\"Move at Alpha done. Now proposing: %+v\", p)\n\tspan.AddEvent(fmt.Sprintf(\"Zero proposal: %+v\", p))\n\tglog.Info(msg)\n\tif err := s.Node.proposeAndWait(ctx, p); err != nil {\n\t\treturn errors.Wrapf(err, \"while proposing tablet reassignment. Proposal: %+v\", p)\n\t}\n\tmsg = fmt.Sprintf(\"Predicate move done for: [%v] from group %d to %d\\n\",\n\t\tpredicate, srcGroup, dstGroup)\n\tspan.AddEvent(msg)\n\tglog.Info(msg)\n\n\t// Now that the move has happened, we can delete the predicate from the source group. But before\n\t// doing that, we should ensure the source group understands that the predicate is now being\n\t// served by the destination group. For that, we pass in the expected checksum for the source\n\t// group. Only once the source group membership checksum matches, would the source group delete\n\t// the predicate. This ensures that it does not service any transaction after deletion of data.\n\tchecksums := s.groupChecksums()\n\tin.ExpectedChecksum = checksums[in.SourceGid]\n\tin.DestGid = 0 // Indicates deletion of predicate in the source group.\n\tif _, err := wc.MovePredicate(ctx, in); err != nil {\n\t\tmsg = fmt.Sprintf(\"While deleting predicate [%v] in group %d. Error: %v\",\n\t\t\tin.Predicate, in.SourceGid, err)\n\t\tspan.AddEvent(msg)","sourceCodeStart":207,"sourceCodeEnd":243,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/dgraph/cmd/zero/tablet.go#L207-L243","documentation":"This error wraps a failure from Zero's raft proposeAndWait call when moving a predicate (tablet) from one group to another. movePredicate proposes a MembershipChange/MoveTablet proposal to the Zero raft ring; if the proposal is not committed (lost leadership, shutdown, context cancel), the underlying error is wrapped with the full proposal for diagnosis.","triggerScenarios":"Calling /moveTablet or rebalanceTablets when Zero loses leadership mid-proposal, the raft quorum is unavailable, or the context is canceled before the proposal is committed.","commonSituations":"Rebalancing tablets in a cluster with only one healthy Zero (no quorum); issuing moveTablet during a Zero restart; network partition between Zero nodes while a rebalance is running.","solutions":["Check Zero cluster health and ensure a leader exists (curl localhost:6080/state), then retry the move after quorum is restored.","Retry the moveTablet request; rebalanceTablets runs periodically and will retry automatically.","Verify the predicate is not already served by the destination group (the move may have partially applied).","Inspect Zero logs for the underlying raft error (lost leadership, no quorum) preceding this wrap."],"exampleFix":"// before\ns.Node.proposeAndWait(ctx, p)\n// after\nctx, cancel := context.WithTimeout(ctx, 30*time.Second)\ndefer cancel()\nif err := s.Node.proposeAndWait(ctx, p); err != nil {\n    glog.Errorf(\"tablet move failed, will retry: %v\", err)\n    return err\n}","handlingStrategy":"retry","validationCode":"state := fetchZeroState(\"http://zero:6080/state\")\nif !state.HasZeroLeader() { return errors.New(\"no Zero leader; cannot move tablet\") }","typeGuard":null,"tryCatchPattern":"err := moveTablet(ctx, predicate, src, dst)\nif err != nil && strings.Contains(err.Error(), \"while proposing tablet reassignment\") {\n    // wait for quorum/leadership, then retry\n    time.Sleep(10 * time.Second)\n    return moveTablet(ctx, predicate, src, dst)\n}","preventionTips":["Maintain at least 3 Zero nodes so raft proposals retain quorum.","Monitor Zero leader availability and pause rebalances when no leader exists.","Use conservative contexts with timeouts so moves don't hang on lost quorum.","Let automatic rebalancing retry rather than issuing manual moves during instability."],"tags":["raft","zero","cluster-administration","tablet-rebalance"],"backgroundTag":"raft-proposal-failed","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}