vitessio/vitess · error
non-contiguous KeyRange values for %v in cell %v at shard %v
Error message
non-contiguous KeyRange values for %v in cell %v at shard %v to %v: %v != %v
What it means
OrderAndCheckPartitions validates that the shard partitions stored in a SrvKeyspace are complete and correctly ordered. For sharded keyspaces, adjacent shards in a partition must have KeyRanges where one shard's End equals the next shard's Start; this error is thrown when a gap or overlap exists between shard i and shard i+1. It fires only for the non-custom-sharding case (custom sharding keyspaces allow all-nil KeyRanges).
Source
Thrown at go/vt/topo/srv_keyspace.go:717
}
last := partition.ShardReferences[len(partition.ShardReferences)-1]
if last.KeyRange != nil && len(last.KeyRange.End) != 0 {
return fmt.Errorf("keyspace partition for %v in cell %v does not end with max key", tabletType, cell)
}
for i := range partition.ShardReferences[0 : len(partition.ShardReferences)-1] {
currShard := partition.ShardReferences[i]
nextShard := partition.ShardReferences[i+1]
currHasKeyRange := currShard.KeyRange != nil
nextHasKeyRange := nextShard.KeyRange != nil
if currHasKeyRange != nextHasKeyRange {
return fmt.Errorf("shards with inconsistent KeyRanges for %v in cell %v. shards: %v, %v", tabletType, cell, currShard, nextShard)
}
if !currHasKeyRange {
// this is the custom sharding case, all KeyRanges must be nil
continue
}
if !key.KeyRangeContiguous(currShard.KeyRange, nextShard.KeyRange) {
return fmt.Errorf("non-contiguous KeyRange values for %v in cell %v at shard %v to %v: %v != %v", tabletType, cell, i, i+1, hex.EncodeToString(currShard.KeyRange.End), hex.EncodeToString(nextShard.KeyRange.Start))
}
}
}
return nil
}
// ValidateSrvKeyspace validates that the SrvKeyspace for given keyspace in the provided cells is not corrupted
func (ts *Server) ValidateSrvKeyspace(ctx context.Context, keyspace, cells string) error {
cellsToValidate, err := ts.ExpandCells(ctx, cells)
if err != nil {
return err
}
for _, cell := range cellsToValidate {
srvKeyspace, err := ts.GetSrvKeyspace(ctx, cell, keyspace)
if err != nil {
return err
}View on GitHub (pinned to 01a25a7d17)
Solutions
- Run `vtctldclient RebuildKeyspaceGraph` (or the equivalent topo rebuild) after any manual shard creation/deletion so SrvKeyspace partitions are regenerated from actual Shard records.
- Compare the two hex KeyRange boundaries printed in the error against `vtctldclient GetShards <keyspace>`; fix the Shard record whose Start/End is wrong (or delete/recreate the bad shard).
- Check whether the keyspace was created with `--served-from`/custom sharding (`SidecarDBName`/durability policy 'none' style custom sharding); if it is a custom-sharding keyspace, ensure all shards have nil KeyRanges, since the check is skipped only in that case.
- If mid-reshard, verify source and target shards both exist with the correct split ranges and rebuild the keyspace graph again after resharding completes.
Example fix
// before (manually created shards with a gap) vtctldclient CreateShard commerce "-80" vtctldclient CreateShard commerce "40-c0" // gap: 80-40 missing // after (contiguous ranges) vtctldclient CreateShard commerce "-80" vtctldclient CreateShard commerce "80-" vtctldclient RebuildKeyspaceGraph commerce
Defensive patterns
Strategy: validation
Validate before calling
// Before creating shards, verify contiguity client-side
func checkContiguous(shards []*topodatapb.Shard) error {
for i := 0; i+1 < len(shards); i++ {
a, b := shards[i].KeyRange, shards[i+1].KeyRange
if a == nil || b == nil {
return fmt.Errorf("shard %d missing keyrange", i)
}
if !bytes.Equal(a.End, b.Start) {
return fmt.Errorf("gap between shard %d and %d", i, i+1)
}
}
return nil
} Type guard
func hasNilKeyRange(kr *topodatapb.KeyRange) bool { return kr == nil || kr.Start == nil && kr.End == nil } Prevention
- Always create shards via a plan that computes split boundaries programmatically, never by hand-typing hex ranges.
- Run `vtctldclient ValidateKeyspace` after any manual topo surgery.
- Rebuild the keyspace graph after resharding completes before serving traffic.
- Mark custom-sharding keyspaces correctly so the nil-KeyRange path is used.
When it happens
Trigger: Calling topo Server methods that rebuild or validate a SrvKeyspace (RebuildKeyspaceLocked, ValidateSrvKeyspace) when the shard list for a tablet type in a cell has adjacent shards with mismatched/gapped KeyRanges, e.g. shard ranges [-80, 40-] instead of [-40, 40-], or manually created shards with wrong boundaries.
Common situations: Manually creating shards with hand-typed keyrange boundaries; a resharding that left old/new shards coexisting in the SrvKeyspace; deleting a shard without rebuilding the keyspace; importing an external cluster with inconsistent shard maps; custom sharding keyspaces accidentally treated as standard sharding (or vice versa).
Related errors
- shard %v/%v has a different KeyRange: %v != %v
- same keyrange is present in source and target: %v
- source and target keyranges don't match: %v vs %v
- cannot rebuild %v: %v
- unexpected in_keyrange parameter: %v
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/26312cd074ed62ba.
Report an issue: GitHub.