vitessio/vitess · error

the shard count must be > 0: %v

Error message

the shard count must be > 0: %v

What it means

EvenShardsKeyRange(i, n) computes the i-th keyrange when a keyspace is evenly split into n power-of-two shards. It throws this when n <= 0, because a non-positive shard count is meaningless and would cause division/modulo errors downstream.

Source

Thrown at go/vt/key/key.go:342

// EvenShardsKeyRange returns a key range definition for a shard at index "i",
// assuming range based sharding with "n" equal-width shards in total.
// i starts at 0.
//
// Example: (1, 2) returns the second out of two shards in total i.e. "80-".
//
// 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

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Pass a positive shard count (e.g. EvenShardsKeyRange(0, 256)).
  2. Validate that the shard count is parsed correctly from flags/config before calling.
  3. Guard the call: skip computing ranges until a valid n is available.

Example fix

// before
count := cfg.Shards // 0 when unset
kr, err := key.EvenShardsKeyRange(i, count)
// after
if cfg.Shards <= 0 {
    return fmt.Errorf("--shards must be > 0")
}
kr, err := key.EvenShardsKeyRange(i, cfg.Shards)
Defensive patterns

Strategy: validation

Validate before calling

if shards <= 0 {
	return fmt.Errorf("shard count must be > 0, got %d", shards)
}

Try / catch

kr, err := key.EvenShardsKeyRange(i, n)
if err != nil {
	return nil, fmt.Errorf("even shards: %w", err)
}

Prevention

When it happens

Trigger: Calling EvenShardsKeyRange with n == 0 or n < 0, e.g. EvenShardsKeyRange(0, 0) or EvenShardsKeyRange(2, -4), typically from misparsed user input or a config that supplied an empty/invalid shard count.

Common situations: CLI/script passing an unset or zero shard count, config placeholder (e.g. '--shards=0') never filled in, integer parsing failures silently yielding 0.

Related errors


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