vitessio/vitess · error
shard %v/%v has no source shard
Error message
shard %v/%v has no source shard
What it means
WaitForFilteredReplication waits until replication lag on a shard's primary (from its SourceShards) drops below a maxDelay. It requires the shard to have at least one SourceShard; a shard with none is not receiving filtered replication, so there is nothing to wait for and the call fails immediately.
Source
Thrown at go/vt/wrangler/split.go:86
// so let's be safe and abort right here.
if len(si.SourceShards) > 0 {
return fmt.Errorf("shard %v/%v already has SourceShards, not overwriting them (full record: %v)", keyspace, shard, si.Shard)
}
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))View on GitHub (pinned to 01a25a7d17)
Solutions
- Verify with `vtctldclient GetShard <keyspace>/<shard>` that source_shards is non-empty; if empty, complete the MoveTables/Reshard step that adds it first.
- Confirm you are targeting the destination shard, not the source shard.
- If migration finished and sources were removed, the wait is unnecessary — skip it.
Example fix
// before vtctldclient WaitForFilteredReplication customer/0 30s // error: shard customer/0 has no source shard // after vtctldclient MoveTables --workflow ledger --source commerce customer # sets up source shard vtctldclient WaitForFilteredReplication customer/0 30s
Defensive patterns
Strategy: validation
Validate before calling
// Before WaitForFilteredReplication, ensure the shard has sources
shardInfo, _ := vtctldclientGetShard(keyspace, shard)
if len(shardInfo.SourceShards) == 0 {
// run MoveTables/Reshard step that configures filtered replication first
fmt.Printf("%s/%s has no SourceShards; configure filtered replication first\n", keyspace, shard)
} Prevention
- Only call the wait on destination shards after MoveTables/Reshard set up sources
- Confirm you're targeting the destination, not the source shard
- In pipelines, assert source_shards non-empty before waiting
When it happens
Trigger: Calling WaitForFilteredReplication (via `vtctldclient WaitForFilteredReplication <keyspace/shard> <maxDelay>`) on a shard whose record has an empty SourceShards list.
Common situations: Running the wait command before MoveTables/Reshard actually configured the source shard; specifying the source keyspace/shard instead of the destination; automation calling wait after the migration completed and sources were removed.
Related errors
- no SourceShard with uid %v
- uid %v is already in use
- shard %v/%v has no primary
- can't rebuild serving keyspace while a migration is on going
- same keyrange is present in source and target: %v
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/a59c80eb1add64c4.
Report an issue: GitHub.