vitessio/vitess · error
shard: %s does not have a primary
Error message
shard: %s does not have a primary
What it means
During TabletExecutor.Open, the executor lists all shards of the keyspace and refuses to proceed if any shard has no primary tablet. Vitess cannot run schema management against a shard without an elected primary.
Source
Thrown at go/vt/schemamanager/tablet_executor.go:123
// hasProvidedUUIDs returns true when UUIDs were provided
func (exec *TabletExecutor) hasProvidedUUIDs() bool {
return len(exec.uuids) != 0
}
// Open opens a connection to the primary for every shard.
func (exec *TabletExecutor) Open(ctx context.Context, keyspace string) error {
if !exec.isClosed {
return nil
}
exec.keyspace = keyspace
shards, err := exec.ts.FindAllShardsInKeyspace(ctx, keyspace, nil)
if err != nil {
return fmt.Errorf("unable to get shards for keyspace: %s, error: %v", keyspace, err)
}
exec.tablets = make([]*topodatapb.Tablet, 0, len(shards))
for shardName, shardInfo := range shards {
if !shardInfo.HasPrimary() {
return fmt.Errorf("shard: %s does not have a primary", shardName)
}
tabletInfo, err := exec.ts.GetTablet(ctx, shardInfo.PrimaryAlias)
if err != nil {
return fmt.Errorf("unable to get primary tablet info, keyspace: %s, shard: %s, error: %v", keyspace, shardName, err)
}
exec.tablets = append(exec.tablets, tabletInfo.Tablet)
}
if len(exec.tablets) == 0 {
return fmt.Errorf("keyspace: %s does not contain any primary tablets", keyspace)
}
exec.isClosed = false
return nil
}
// Validate validates a list of sql statements.
func (exec *TabletExecutor) Validate(ctx context.Context, sqls []string) error {
if exec.isClosed {View on GitHub (pinned to 01a25a7d17)
Solutions
- Fix replication on the affected shard: run `vttablet`/`vtctl InitShardPrimary` (or PlannedReparentShard) to elect a primary
- Verify shard state with `vtctl GetShard <keyspace>/<shard>` and confirm PrimaryAlias is set
- If the shard should not exist, remove it with `vtctl DeleteShard` or correct the keyspace targeted by the schema operation
- Retry the schema application once all shards have primaries
Example fix
// before: applying schema to keyspace with empty shard vtctlclient ApplySchema -sql "..." commerce // after: ensure primary exists first, or prune empty shards vtctlclient RemoveKeyspace -recursive empty_ks vtctlclient ApplySchema -sql "..." commerce
Defensive patterns
Strategy: validation
Validate before calling
shards, err := ts.GetShardMap(ctx, keyspace)
if err != nil { return err }
for name, info := range shards {
if !info.HasPrimary() {
return fmt.Errorf("shard %s has no primary; fix topology before ApplySchema", name)
}
} Type guard
func shardHasPrimary(s *topodatapb.Shard) bool {
return s != nil && s.PrimaryAlias != nil && s.PrimaryAlias.Uid != 0
} Try / catch
if err := executor.Open(ctx, keyspace); err != nil {
if strings.Contains(err.Error(), "does not have a primary") {
return fmt.Errorf("keyspace %s not ready for schema change: %w", keyspace, err)
}
return err
} Prevention
- Check GetShard for PrimaryAlias before schema operations
- Elect primaries with PlannedReparentShard before maintenance windows
- Avoid running ApplySchema during resharding until target shards have primaries
When it happens
Trigger: Calling schemamanager (e.g. ApplySchema via tablet_executor) when one or more shards of the target keyspace lack a primary (ShardInfo.HasPrimary() == false), typically after a failed primary election or an empty/disabled keyspace.
Common situations: Running ApplySchema on a keyspace with a shard still in orphaned state, a shard whose primary alias was pruned by the new shard pruning policy, or during resharding when the target shard has no primary yet.
Related errors
- no primary tablet found
- unable to get shards for keyspace: %s, error: %v
- source shard has no primary: %v
- not allowed: deny-all security-policy enforced
- not allowed: read-only security-policy enforced
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/44ba2cb77627d804.
Report an issue: GitHub.