vitessio/vitess · error
could not find primary tablet %v
Error message
could not find primary tablet %v
What it means
restartDirectReplicas must locate the current primary tablet record in VTOrc's DB to enumerate its direct replicas before restarting replication on them. When no matching primary tablet exists for the analyzed instance alias, recovery cannot proceed and this error is returned (after also logging it via logger.Error).
Source
Thrown at go/vt/vtorc/logic/topology_recovery.go:562
// Get all tablets in the shard
tablets, err := getShardTablets(ctx, analysisEntry.AnalyzedKeyspace, analysisEntry.AnalyzedShard)
if err != nil {
logger.Error(fmt.Sprintf("Error fetching tablets for keyspace/shard %v/%v: %v", analysisEntry.AnalyzedKeyspace, analysisEntry.AnalyzedShard, err))
return false, topologyRecovery, err
}
// Find the primary tablet for semi-sync policy determination
var primaryTablet *topodatapb.Tablet
for _, tabletInfo := range tablets {
if topoproto.TabletAliasEqual(tabletInfo.Alias, analysisEntry.AnalyzedInstanceAlias) {
primaryTablet = tabletInfo.Tablet
break
}
}
if primaryTablet == nil {
logger.Error("Could not find primary tablet " + topoproto.TabletAliasString(analysisEntry.AnalyzedInstanceAlias))
return false, topologyRecovery, fmt.Errorf("could not find primary tablet %v", topoproto.TabletAliasString(analysisEntry.AnalyzedInstanceAlias))
}
eg, _ := errgroup.WithContext(ctx)
var restartExpected int
var restartPerformed atomic.Int64
// Iterate through all tablets and find direct replicas of the primary.
// We intentionally shuffle tablet order. When maxReplicas is non-zero, we want to
// randomly pick which replicas to restart, to avoid biasing towards replicas.
for i, tabletIndex := range rand.Perm(len(tablets)) {
if maxReplicas > 0 && i >= maxReplicas {
break
}
tabletInfo := tablets[tabletIndex]
tablet := tabletInfo.Tablet
tabletAliasString := topoproto.TabletAliasString(tablet.Alias)
// Skip the primary itself
if topoproto.TabletAliasEqual(tablet.Alias, analysisEntry.AnalyzedInstanceAlias) {View on GitHub (pinned to 01a25a7d17)
Solutions
- Run a tablet refresh (vtorc refresh or wait for the discovery loop) so the tablet map includes the current primary
- Verify the tablet exists with `vtctldclient GetTablets` and that its alias matches what the recovery analysis references
- Re-prime VTOrc's DB: delete stale tablet rows and let Rediscovery repopulate, then re-trigger the recovery
- If the primary is genuinely gone, use a different recovery action (e.g. EmergencyReparentShard) rather than replica-restart
Defensive patterns
Strategy: validation
Validate before calling
tablet, err := inst.ReadTablet(alias)
if err != nil || tablet == nil {
return fmt.Errorf("primary tablet %s not present; refresh discovery before recovery", aliasStr)
} Prevention
- Let the discovery loop refresh tablet data before triggering manual recoveries
- Avoid removing tablets from topo while recoveries are pending
- Use vtctldclient GetTablets to confirm aliases before scripted failovers
When it happens
Trigger: A recovery (restartArbitraryDirectReplica / restartAllDirectReplicas) runs for an analysis entry whose AnalyzedInstanceAlias has no corresponding primary Tablet record in the vtorc DB — e.g. the tablet record was pruned, the tablet was replaced/re-aliased, or replication mid-level topology changed so no primary candidate is found.
Common situations: Tablet was deleted from topology while recovery was in flight; emergency repair after keyspace resharding left stale aliases; VTOrc's DB hasn't finished refreshing tablets from topo; mistake in the analyzed instance alias.
Related errors
- no primary tablet found
- ParseBinlogCoordinates: Cannot parse BinlogCoordinates from
- ParseBinlogCoordinates: invalid pos: %s
- failed to read tablet %q from vtorc db: %w
- failed to ensure replication was started on tablet %s after
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/5d0fdd549962f7c0.
Report an issue: GitHub.