vitessio/vitess · error · ErrNoPrimaryTablet
no primary tablet found
Error message
no primary tablet found
What it means
ErrNoPrimaryTablet is the sentinel returned by shardPrimary when a shard has no elected primary tablet. It signals the shard's primary alias is empty in the topo record, so primary-dependent operations cannot proceed.
Source
Thrown at go/vt/vtorc/logic/tablet_discovery.go:65
var (
ts *topo.Server
tmc tmclient.TabletManagerClient
clustersToWatch []string
cellsNoRecovery []string
shutdownWaitTime = 30 * time.Second
// cellsNoRecoveryValidated is true once validateCellsNoRecovery has confirmed
// every entry in cellsNoRecovery exists in the topology. It starts false when
// the flag is set but the topo was unreachable at startup; recovery is blocked
// until a subsequent refresh cycle can complete validation.
cellsNoRecoveryValidated atomic.Bool
// shardsToWatch is a map storing the shards for a given keyspace that need to be watched.
// We store the key range for all the shards that we want to watch.
// This is populated by parsing `--clusters_to_watch` flag.
shardsToWatch map[string][]*topodatapb.KeyRange
// ErrNoPrimaryTablet is a fixed error message.
ErrNoPrimaryTablet = errors.New("no primary tablet found")
)
func init() {
stats.NewGaugesFuncWithMultiLabels(
"TabletsWatchedByCell",
"Number of tablets watched by cell",
[]string{"Cell"},
getTabletsWatchedByCellStats,
)
stats.NewGaugesFuncWithMultiLabels(
"TabletsWatchedByShard",
"Number of tablets watched by keyspace/shard",
[]string{"Keyspace", "Shard"},
getTabletsWatchedByShardStats,
)
stats.NewGaugesFuncWithMultiLabels(
"EmergencyReparentShardDisabled",
"Shards with EmergencyReparentShard disabled by keyspace/shard (1 = disabled)",View on GitHub (pinned to 01a25a7d17)
Solutions
- Elect a primary: vtctldclient PlannedReparentShard or EmergencyReparentShard for the keyspace/shard.
- Check tablet health and replication status if the primary election failed.
- Wait and retry — during an in-flight reparent the primary record is temporarily empty; vtorc retries on subsequent ticks.
Example fix
// before
prim, err := shardPrimary(ctx, keyspace, shard)
if err != nil { return err }
// after
prim, err := shardPrimary(ctx, keyspace, shard)
if errors.Is(err, ErrNoPrimaryTablet) {
return fmt.Errorf("shard %s/%s has no primary; run PlannedReparentShard first", keyspace, shard)
} else if err != nil { return err } Defensive patterns
Strategy: retry
Validate before calling
// before primary-dependent work
shardInfo, err := ts.GetShard(ctx, keyspace, shard)
if err != nil { return err }
if shardInfo.GetPrimaryAlias() == nil {
return ErrNoPrimaryTablet
} Type guard
func shardHasPrimary(si *topo.ShardInfo) bool {
return si != nil && si.GetPrimaryAlias() != nil
} Try / catch
prim, err := shardPrimary(ctx, keyspace, shard)
if errors.Is(err, ErrNoPrimaryTablet) {
// wait for reparent / election to finish, retry next tick
return nil
} else if err != nil { return err } Prevention
- Ensure every shard has an elected primary (InitShardPrimary after creation).
- Monitor reparent operations and retry logic around them.
- Check ShardInfo primary alias before primary-dependent operations.
When it happens
Trigger: shardPrimary lookup for a keyspace/shard whose record has no primary — during initial cluster setup, after a failed PrimaryElect, or while reparenting is in flight.
Common situations: Freshly created shard before InitShardPrimary; primary tablet down mid-reparenting leaving the record unset; vtorc scanning a shard concurrently with vtctl reparent operations.
Related errors
- shard not found
- shard %s/%s has no primary
- cannot lookup primary tablet %v for shard %v/%v: %w
- no primary in shard %v/%v
- failed to read shard primary for %s/%s: %w
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/9548d6a81918dde1.
Report an issue: GitHub.