vitessio/vitess · error
shard %v/%v has no primary
Error message
shard %v/%v has no primary
What it means
WaitForFilteredReplication reads replication lag from the shard's primary tablet, addressed via the shard record's PrimaryAlias. If the shard record has no primary (PrimaryAlias unset), lag cannot be measured and the call fails.
Source
Thrown at go/vt/wrangler/split.go:89
}
si.SourceShards = sourceShards
return nil
})
return err
}
// WaitForFilteredReplication will wait until the Filtered Replication process has finished.
func (wr *Wrangler) WaitForFilteredReplication(ctx context.Context, keyspace, shard string, maxDelay time.Duration) error {
shardInfo, err := wr.TopoServer().GetShard(ctx, keyspace, shard)
if err != nil {
return err
}
if len(shardInfo.SourceShards) == 0 {
return fmt.Errorf("shard %v/%v has no source shard", keyspace, shard)
}
if !shardInfo.HasPrimary() {
return fmt.Errorf("shard %v/%v has no primary", keyspace, shard)
}
alias := shardInfo.PrimaryAlias
tabletInfo, err := wr.TopoServer().GetTablet(ctx, alias)
if err != nil {
return err
}
// Always run an explicit healthcheck first to make sure we don't see any outdated values.
// This is especially true for tests and automation where there is no pause of multiple seconds
// between commands and the periodic healthcheck did not run again yet.
if err := wr.TabletManagerClient().RunHealthCheck(ctx, tabletInfo.Tablet); err != nil {
return fmt.Errorf("failed to run explicit healthcheck on tablet: %v err: %v", tabletInfo, err)
}
conn, err := tabletconn.GetDialer()(ctx, tabletInfo.Tablet, grpcclient.FailFast(false))
if err != nil {
return fmt.Errorf("cannot connect to tablet %v: %v", alias, err)
}View on GitHub (pinned to 01a25a7d17)
Solutions
- Complete primary initialization: `vtctldclient InitShardPrimary <keyspace/shard> <tablet-alias>` (or let the workflow's planned rebalance/primary election finish).
- Check `vtctldclient GetShard <keyspace>/<shard>` — primary_alias must be set — then re-run the wait.
- If the shard is genuinely headless (no primary intended), WaitForFilteredReplication cannot be used for it.
Example fix
// before vtctldclient WaitForFilteredReplication customer/0 30s // error: shard customer/0 has no primary // after vtctldclient InitShardPrimary customer/0 zone1-101 vtctldclient WaitForFilteredReplication customer/0 30s
Defensive patterns
Strategy: validation
Validate before calling
// Before waiting, ensure the shard has a primary
shardInfo, _ := vtctldclientGetShard(keyspace, shard)
if shardInfo.PrimaryAlias == nil || shardInfo.PrimaryAlias.Uid == 0 {
// run InitShardPrimary first
fmt.Printf("%s/%s has no primary; run InitShardPrimary\n", keyspace, shard)
} Prevention
- Complete InitShardPrimary on new shards before waiting for filtered replication
- Check primary_alias in GetShard output as a pipeline precondition
- Never assume a freshly created shard has a primary
When it happens
Trigger: Calling WaitForFilteredReplication on a destination shard whose record lacks a primary — e.g. InitShardPrimary was never run on the new shard, or the primary was lost and the record cleared.
Common situations: Reshard workflow creating a new shard but primary election/InitShardPrimary not completed yet; running wait before tablets in the new shard were started and promoted.
Related errors
- no SourceShard with uid %v
- uid %v is already in use
- shard %v/%v has no source shard
- creating this tablet would override old primary %v in shard
- can't rebuild serving keyspace while a migration is on going
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/c1c82717f02b4b07.
Report an issue: GitHub.