vitessio/vitess · error

--buffer-keyspace-shards has overlapping entries (keyspace…

Error message

--buffer-keyspace-shards has overlapping entries (keyspace only vs. keyspace/shard): %v vs. %v Please remove one or the other

What it means

--buffer-keyspace-shards accepts either whole keyspaces (ks) or specific keyspace/shard pairs (ks/shard). Listing both forms for the same keyspace is ambiguous, so verifyFlags detects the overlap via keyspaceShardsToSets and rejects the configuration.

Solutions

  1. Keep only the bare keyspace entry to buffer all its shards, e.g. --buffer-keyspace-shards=ks1
  2. Or keep only the explicit shard entries and delete the bare keyspace entry
  3. Re-run/validate with TestVerifyFlags-style verification before rollout

Example fix

// before
--buffer-keyspace-shards=commerce commerce/-80
// after
--buffer-keyspace-shards=commerce
Defensive patterns

Strategy: validation

Validate before calling

keyspaces, shards := keyspaceShardsToSets(bufferKeyspaceShards)
for s := range shards {
    keyspace, _, err := topoproto.ParseKeyspaceShard(s)
    if err != nil { return err }
    if keyspaces[keyspace] {
        return fmt.Errorf("overlapping entries: %v vs %v", keyspace, s)
    }
}

Prevention

When it happens

Trigger: Setting --buffer-keyspace-shards like 'ks1 ks1/-80' where both the bare keyspace and a shard of the same keyspace appear.

Common situations: Incrementally growing the flag from a shard-specific list to a whole keyspace without removing the shard entries; merging flag values from multiple config sources.

Understand the failure class

Background: "unknown output mode", "invalid value for flag", "expects true/false": fixing invalid flag value errors in CLI tools — this error's family across 24 libraries.

Related errors


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

Appendix: source

Thrown at go/vt/vtgate/buffer/flags.go:97

	if bufferDrainConcurrency < 1 {
		return fmt.Errorf("--buffer-drain-concurrency must be >= 1 (specified value: %d)", bufferDrainConcurrency)
	}

	if bufferKeyspaceShards != "" && !bufferEnabled {
		return fmt.Errorf("--buffer-keyspace-shards=%v also requires that --enable_buffer is set", bufferKeyspaceShards)
	}
	if bufferEnabled && bufferEnabledDryRun && bufferKeyspaceShards == "" {
		return errors.New("both the dry-run mode and actual buffering is enabled. To avoid ambiguity, keyspaces and shards for actual buffering must be explicitly listed in --buffer-keyspace-shards")
	}

	keyspaces, shards := keyspaceShardsToSets(bufferKeyspaceShards)
	for s := range shards {
		keyspace, _, err := topoproto.ParseKeyspaceShard(s)
		if err != nil {
			return err
		}
		if keyspaces[keyspace] {
			return fmt.Errorf("--buffer-keyspace-shards has overlapping entries (keyspace only vs. keyspace/shard): %v vs. %v Please remove one or the other", keyspace, s)
		}
	}

	return nil
}

// keyspaceShardsToSets converts a comma separated list of keyspace[/shard]
// entries to two sets: keyspaces (if the shard is not specified) and shards (if
// both keyspace and shard is specified).
func keyspaceShardsToSets(list string) (map[string]bool, map[string]bool) {
	keyspaces := make(map[string]bool)
	shards := make(map[string]bool)
	if list == "" {
		return keyspaces, shards
	}

	for item := range strings.SplitSeq(list, ",") {
		if strings.Contains(item, "/") {

View on GitHub (pinned to 01a25a7d17)