vitessio/vitess · error
the shard count must be a power of two: %v
Error message
the shard count must be a power of two: %v
What it means
EvenShardsKeyRange requires the shard count n to be a power of two, because even splitting is done by cutting the keyspace in half n-log2(n) times; non-power-of-two counts cannot be represented as clean, equally sized ranges. It throws when n & (n-1) != 0.
Source
Thrown at go/vt/key/key.go:348
//
// This function must not be used in the Vitess code base because Vitess also
// supports shards with different widths. In that case, the output of this
// function would be wrong.
//
// Note: start and end values have trailing zero bytes omitted.
// For example, "80-" has only the first byte (0x80) set.
// We do this to produce the same KeyRange objects as ParseKeyRangeParts() does.
// Because it's using the Go hex methods, it's omitting trailing zero bytes as
// well.
func EvenShardsKeyRange(i, n int) (*topodatapb.KeyRange, error) {
if n <= 0 {
return nil, fmt.Errorf("the shard count must be > 0: %v", n)
}
if i >= n {
return nil, fmt.Errorf("the index of the shard must be less than the total number of shards: %v < %v", i, n)
}
if n&(n-1) != 0 {
return nil, fmt.Errorf("the shard count must be a power of two: %v", n)
}
// Determine the number of bytes which are required to represent any
// KeyRange start or end for the given n.
// This is required to trim the returned values to the same length e.g.
// (256, 512) should return 8000-8080 as shard key range.
minBytes := 0
for nn := Uint64Key(n - 1); nn > 0; nn >>= 8 {
minBytes++
}
width := Uint64Key(math.MaxUint64)/Uint64Key(n) + 1
start := Uint64Key(i) * width
end := start + width
// Note: The byte value is empty if start or end is the min or the max
// respectively.
startBytes := start.Bytes()[:minBytes]View on GitHub (pinned to 01a25a7d17)
Solutions
- Choose a power-of-two shard count: 2, 4, 8, ..., 1024.
- Round the requested shard count up to the next power of two before calling.
- If arbitrary boundaries are needed, use ParseShardingSpec / GenerateShardRanges instead of EvenShardsKeyRange.
Example fix
// before kr, err := key.EvenShardsKeyRange(0, 12) // after kr, err := key.EvenShardsKeyRange(0, 16) // round up to power of two
Defensive patterns
Strategy: validation
Validate before calling
if shards <= 0 || shards&(shards-1) != 0 {
return fmt.Errorf("shard count %d is not a power of two", shards)
} Try / catch
kr, err := key.EvenShardsKeyRange(i, n)
if err != nil {
return nil, fmt.Errorf("even shard range: %w", err)
} Prevention
- Round requested shard counts up to the next power of two
- Use ParseShardRanges/GenerateShardRanges for non-power-of-two layouts
When it happens
Trigger: Calling EvenShardsKeyRange with any n that is not 2^k, e.g. EvenShardsKeyRange(0, 12) or EvenShardsKeyRange(1, 100).
Common situations: Users specifying desired shard counts like 10, 12, 100 in configs; scripts rounding shard counts to arbitrary values; confusion between 'even shard ranges' and arbitrary-range sharding.
Related errors
- malformed spec: MinKey/MaxKey cannot be in the middle of the
- malformed spec: shard limits should be in order: %q
- the shard count must be > 0: %v
- the index of the shard must be less than the total number of
- the given number of shards (%d) is too high for the given nu
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/ddbebe0e52616d47.
Report an issue: GitHub.