vitessio/vitess · error

shard %v/%v already has SourceShards, not overwriting them (

Error message

shard %v/%v already has SourceShards, not overwriting them (full record: %v)

What it means

This guard in split.go (used by restore-style workflows such as InitShardPrimary flows in legacy ReshardRestoreData) refuses to overwrite existing SourceShards on a shard. If the shard already has SourceShards, it may already have been restored, so overwriting could corrupt the replication configuration.

Source

Thrown at go/vt/wrangler/split.go:70

	// So iterating over the sourceTablets map would be a bad idea.
	sourceShards := make([]*topodatapb.Shard_SourceShard, len(sourceTablets))
	for i, alias := range sources {
		ti := sourceTablets[topoproto.TabletAliasString(alias)]
		sourceShards[i] = &topodatapb.Shard_SourceShard{
			Uid:      int32(i),
			Keyspace: ti.Keyspace,
			Shard:    ti.Shard,
			KeyRange: ti.KeyRange,
			Tables:   tables,
		}
	}

	// Update the shard with the new source shards.
	_, err = wr.ts.UpdateShardFields(ctx, keyspace, shard, func(si *topo.ShardInfo) error {
		// If the shard already has sources, maybe it's already been restored,
		// 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() {

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Inspect the shard record (`vtctldclient GetShard`) to confirm the existing SourceShards are from a prior successful restore; if so, the restore already happened — skip it.
  2. If the existing SourceShards are stale leftovers from a failed run, remove them (SourceShardDelete for each uid) and re-run the restore.
  3. Verify you are targeting the correct destination keyspace/shard.

Example fix

// before
vtctldclient SourceShardDelete commerce/0 0   # remove stale entry
vtctldclient GetShard commerce/0              # verify source_shards: []
// then re-run the restore/split workflow
Defensive patterns

Strategy: validation

Validate before calling

// Before running a restore/split workflow, verify destination has no SourceShards
shardInfo, _ := vtctldclientGetShard(dstKeyspace, dstShard)
if len(shardInfo.SourceShards) > 0 {
    fmt.Printf("destination %s/%s already has %d SourceShards; restore likely already ran\n",
        dstKeyspace, dstShard, len(shardInfo.SourceShards))
}

Prevention

When it happens

Trigger: Running a legacy split/restore workflow (SplitClone restore path) against a shard that already has filtered replication sources configured — commonly because the restore was partially or fully run before.

Common situations: Re-running a failed reshard restore without cleaning the destination shard's SourceShards; pointing the restore at an already-served shard by mistake.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/b1cca7823ef2ee5a. Report an issue: GitHub.