{"record":{"id":"374d0e4a891040bb","repo":"vitessio/vitess","slug":"primary-elect-tablet-v-is-not-the-shard-primary","errorCode":null,"errorMessage":"primary-elect tablet %v is not the shard primary, use -force to proceed anyway","messagePattern":"primary-elect tablet (.+?) is not the shard primary, use -force to proceed anyway","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtctl/grpcvtctldserver/server.go","lineNumber":2877,"sourceCode":"\tevent.DispatchUpdate(ev, \"reading tablet map\")\n\ttabletMap, err := s.ts.GetTabletMapForShard(ctx, req.Keyspace, req.Shard)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Check the primary elect is in tabletMap.\n\tprimaryElectTabletAliasStr := topoproto.TabletAliasString(req.PrimaryElectTabletAlias)\n\tprimaryElectTabletInfo, ok := tabletMap[primaryElectTabletAliasStr]\n\tif !ok {\n\t\treturn fmt.Errorf(\"primary-elect tablet %v is not in the shard\", topoproto.TabletAliasString(req.PrimaryElectTabletAlias))\n\t}\n\tev.NewPrimary = primaryElectTabletInfo.CloneVT()\n\n\t// Check the primary is the only primary is the shard, or -force was used.\n\t_, primaryTabletMap := topotools.SortedTabletMap(tabletMap)\n\tif !topoproto.TabletAliasEqual(shardInfo.PrimaryAlias, req.PrimaryElectTabletAlias) {\n\t\tif !req.Force {\n\t\t\treturn fmt.Errorf(\"primary-elect tablet %v is not the shard primary, use -force to proceed anyway\", topoproto.TabletAliasString(req.PrimaryElectTabletAlias))\n\t\t}\n\n\t\tlogger.Warningf(\"primary-elect tablet %v is not the shard primary, proceeding anyway as -force was used\", topoproto.TabletAliasString(req.PrimaryElectTabletAlias))\n\t}\n\tif _, ok := primaryTabletMap[primaryElectTabletAliasStr]; !ok {\n\t\tif !req.Force {\n\t\t\treturn fmt.Errorf(\"primary-elect tablet %v is not a primary in the shard, use -force to proceed anyway\", topoproto.TabletAliasString(req.PrimaryElectTabletAlias))\n\t\t}\n\t\tlogger.Warningf(\"primary-elect tablet %v is not a primary in the shard, proceeding anyway as -force was used\", topoproto.TabletAliasString(req.PrimaryElectTabletAlias))\n\t}\n\thaveOtherPrimary := false\n\tfor alias := range primaryTabletMap {\n\t\tif primaryElectTabletAliasStr != alias {\n\t\t\thaveOtherPrimary = true\n\t\t}\n\t}\n\tif haveOtherPrimary {\n\t\tif !req.Force {","sourceCodeStart":2859,"sourceCodeEnd":2895,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtctl/grpcvtctldserver/server.go#L2859-L2895","documentation":"During PlannedReparentShard, if the primary-elect tablet is not the shard's current primary alias in the topo, Vitess refuses to proceed unless req.Force is set, because reparenting to a non-primary would promote a replica and drop the existing primary. The shard's topology is left unchanged on this error.","triggerScenarios":"Calling PlannedReparentShard with --primary-elect-alias pointing to a replica when the shard's current primary is a different tablet, without --force. (Promoting the current primary without an alias, i.e. empty alias, is the normal path.)","commonSituations":"Operators thinking PRS behaves like EmergencyReparentShard, forgetting that a non-empty primary-elect must name the current primary for a clean swap (or must be paired with --force to override).","solutions":["Use --force if you really want to promote this non-primary tablet anyway.","Pass --primary-elect-alias equal to the current primary for a graceful reparent, or omit the alias to just demote/promote cleanly.","Verify shard state with `vtctldclient GetShard` to see who the current primary is before retrying."],"exampleFix":"// before\nvtctldclient PlannedReparentShard commerce/0 --primary-elect-alias zone1-0000000102\n// after (intentional override)\nvtctldclient PlannedReparentShard commerce/0 --primary-elect-alias zone1-0000000102 --force","handlingStrategy":"validation","validationCode":"shardInfo, _ := ts.GetShard(ctx, ks, shard)\nif !topoproto.TabletAliasEqual(shardInfo.PrimaryAlias, req.PrimaryElectTabletAlias) && !force {\n    return fmt.Errorf(\"alias %s is not current primary; add --force or omit alias\",\n        topoproto.TabletAliasString(req.PrimaryElectTabletAlias))\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check shard.PrimaryAlias via GetShard before PRS","Use an empty primary-elect alias for the common 'reparent gracefully' case","Reserve --force for intentional overrides and document why"],"tags":["vitess","reparent","failover","force"],"backgroundTag":"primary-elect-validation-failed","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}