vitessio/vitess · error

mismatched shards for keyspace %s: %s

Error message

mismatched shards for keyspace %s: %s

What it means

This is the aggregate error CompareShards returns when either side (switch command or topo) had extra shards. It joins all recorded shard-set differences into one message keyed by keyspace so the operator sees the full mismatch at once. Validation of the switch operation aborts when this is returned.

Source

Thrown at go/vt/vtctl/workflow/utils.go:522

	}

	topoShardSet := sets.New[string](topoShards...)
	if !shardSet.Equal(topoShardSet) {
		wfExtra := shardSet.Difference(topoShardSet)
		topoExtra := topoShardSet.Difference(shardSet)

		var rec concurrency.AllErrorRecorder
		if wfExtra.Len() > 0 {
			wfExtraSorted := sets.List(wfExtra)
			rec.RecordError(fmt.Errorf("switch command shards not in topo: %v", wfExtraSorted))
		}

		if topoExtra.Len() > 0 {
			topoExtraSorted := sets.List(topoExtra)
			rec.RecordError(fmt.Errorf("topo shards not in switch command: %v", topoExtraSorted))
		}

		return fmt.Errorf("mismatched shards for keyspace %s: %s", keyspace, strings.Join(rec.ErrorStrings(), "; "))
	}

	return nil
}

// HashStreams produces a stable hash based on the target keyspace and migration
// targets.
func HashStreams(targetKeyspace string, targets map[string]*MigrationTarget) int64 {
	var expanded []string
	for shard, target := range targets {
		for uid := range target.Sources {
			expanded = append(expanded, fmt.Sprintf("%s:%d", shard, uid))
		}
	}

	sort.Strings(expanded)

	hasher := fnv.New64()

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Read the semicolon-separated detail after the colon; it lists the exact extra shards on each side.
  2. Fix the -shards list to exactly equal the topo shard set for the keyspace.
  3. Re-run after any reshard/merge so the command reflects the current shard layout.
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check set equality
if !sets.New[string](shards...).Equal(sets.New[string](topoShardsForKeyspace(ks)...)) {
    return fmt.Errorf("shard set mismatch for %s", ks)
}

Try / catch

if err := validate(ks, shards); err != nil {
    if strings.HasPrefix(err.Error(), "mismatched shards for keyspace") {
        // print details and fetch the authoritative shard list
        log.Warn("shard mismatch", slog.Any("error", err))
        shards = topoShardsForKeyspace(ks)
    }
    return err
}

Prevention

When it happens

Trigger: Any SwitchTraffic (or similar validated workflow command) whose -shards set differs from the topo shard set for the keyspace — the two more-specific errors (not in topo / not in switch command) are wrapped into this summary error.

Common situations: Same as the specific mismatches: stale shard lists, typo'd ranges, partial cutovers; the operator often sees only this summary line first.

Related errors


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