vitessio/vitess · error

primary-elect tablet %v is not a primary in the shard, use -

Error message

primary-elect tablet %v is not a primary in the shard, use -force to proceed anyway

What it means

PlannedReparentShard also checks the tablet map: the primary-elect tablet must currently be running as a PRIMARY type tablet in the shard. If it is a replica/rdonly tablet, the RPC refuses to proceed unless --force is given.

Source

Thrown at go/vt/vtctl/grpcvtctldserver/server.go:2884

	primaryElectTabletAliasStr := topoproto.TabletAliasString(req.PrimaryElectTabletAlias)
	primaryElectTabletInfo, ok := tabletMap[primaryElectTabletAliasStr]
	if !ok {
		return fmt.Errorf("primary-elect tablet %v is not in the shard", topoproto.TabletAliasString(req.PrimaryElectTabletAlias))
	}
	ev.NewPrimary = primaryElectTabletInfo.CloneVT()

	// Check the primary is the only primary is the shard, or -force was used.
	_, primaryTabletMap := topotools.SortedTabletMap(tabletMap)
	if !topoproto.TabletAliasEqual(shardInfo.PrimaryAlias, req.PrimaryElectTabletAlias) {
		if !req.Force {
			return fmt.Errorf("primary-elect tablet %v is not the shard primary, use -force to proceed anyway", topoproto.TabletAliasString(req.PrimaryElectTabletAlias))
		}

		logger.Warningf("primary-elect tablet %v is not the shard primary, proceeding anyway as -force was used", topoproto.TabletAliasString(req.PrimaryElectTabletAlias))
	}
	if _, ok := primaryTabletMap[primaryElectTabletAliasStr]; !ok {
		if !req.Force {
			return fmt.Errorf("primary-elect tablet %v is not a primary in the shard, use -force to proceed anyway", topoproto.TabletAliasString(req.PrimaryElectTabletAlias))
		}
		logger.Warningf("primary-elect tablet %v is not a primary in the shard, proceeding anyway as -force was used", topoproto.TabletAliasString(req.PrimaryElectTabletAlias))
	}
	haveOtherPrimary := false
	for alias := range primaryTabletMap {
		if primaryElectTabletAliasStr != alias {
			haveOtherPrimary = true
		}
	}
	if haveOtherPrimary {
		if !req.Force {
			return fmt.Errorf("primary-elect tablet %v is not the only primary in the shard, use -force to proceed anyway", topoproto.TabletAliasString(req.PrimaryElectTabletAlias))
		}
		logger.Warningf("primary-elect tablet %v is not the only primary in the shard, proceeding anyway as -force was used", topoproto.TabletAliasString(req.PrimaryElectTabletAlias))
	}

	// First phase: reset replication on all tablets. If anyone fails,
	// we stop. It is probably because it is unreachable, and may leave

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Verify the tablet's type with `vtctldclient GetTablet <alias>`; if it is actually the primary in practice, fix the topo type (e.g. via EmergencyReparentShard or TabletExternallyReparented).
  2. Use --force to proceed with promotion despite the topo type mismatch.
  3. Re-run PlannedReparentShard without an alias to let Vitess pick the current primary.

Example fix

// before
vtctldclient PlannedReparentShard commerce/0 --primary-elect-alias zone1-0000000102
// after
vtctldclient PlannedReparentShard commerce/0 --primary-elect-alias zone1-0000000102 --force
Defensive patterns

Strategy: validation

Validate before calling

info, ok := tabletMap[topoproto.TabletAliasString(req.PrimaryElectTabletAlias)]
if !ok || info.Tablet.Type != topodatapb.TabletType_PRIMARY {
    if !req.Force { return errors.New("primary-elect is not a PRIMARY tablet") }
}

Prevention

When it happens

Trigger: Calling PlannedReparentShard with --primary-elect-alias naming a tablet whose topo record is not of type PRIMARY (e.g. a REPLICA) and req.Force unset. Typically after a partial prior failover left the shard's type assignments inconsistent.

Common situations: Resuming after a failed reparent where the intended tablet is a replica; stale topo types after an emergency reparent; operator confusion between current and desired primary.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/a5f5d50976747f0a. Report an issue: GitHub.