vitessio/vitess · error

duplicate %v/%v entry

Error message

duplicate %v/%v entry

What it means

NewFilterByShard canonicalizes each shard name (keyranges are normalized) and rejects duplicate entries for the same keyspace with this error, since a duplicate filter shard adds nothing and likely signals a config mistake.

Source

Thrown at go/vt/discovery/topology_watcher.go:376

	for _, filter := range filters {
		parts := strings.Split(filter, "|")
		if len(parts) != 2 {
			return nil, fmt.Errorf("invalid FilterByShard parameter: %v", filter)
		}

		keyspace := parts[0]
		shard := parts[1]

		// extract keyrange if it's a range
		canonical, kr, err := topo.ValidateShardName(shard)
		if err != nil {
			return nil, fmt.Errorf("error parsing shard name %v: %v", shard, err)
		}

		// check for duplicates
		for _, c := range m[keyspace] {
			if c.shard == canonical {
				return nil, fmt.Errorf("duplicate %v/%v entry", keyspace, shard)
			}
		}

		m[keyspace] = append(m[keyspace], &filterShard{
			keyspace: keyspace,
			shard:    canonical,
			keyRange: kr,
		})
	}

	fbs := &FilterByShard{
		filters: m,
		options: withOptions(opts...),
	}

	return fbs, nil
}

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Deduplicate the tablet-filters list, keeping one entry per keyspace|shard pair.
  2. Remember canonicalization: a whole-range entry ('-') may collide with explicit boundaries in single-shard keyspaces — pick one form.
  3. Run the list through NewFilterByShard (or a set keyed on keyspace+canonical shard) before writing the config.
  4. Check the error's %v/%v values to identify the exact colliding keyspace and shard.

Example fix

// before
NewFilterByShard([]string{"commerce|0", "commerce|0"})
// after
NewFilterByShard([]string{"commerce|0"})
Defensive patterns

Strategy: validation

Validate before calling

seen := map[string]bool{}
for _, f := range filters {
	parts := strings.Split(f, "|")
	key := parts[0] + "|" + parts[1]
	if seen[key] {
		return fmt.Errorf("duplicate filter %s", key)
	}
	seen[key] = true
}

Try / catch

fbs, err := discovery.NewFilterByShard(filters)
if err != nil {
	log.Exitf("duplicate entries in tablet-filters: %v", err)
}

Prevention

When it happens

Trigger: Calling NewFilterByShard with two entries that canonicalize to the same keyspace+shard — exact duplicates like 'commerce|0' twice, or aliases like 'commerce|-' vs 'commerce|-80' when the keyspace has a single shard spanning the whole range.

Common situations: Repeating a filter in a long comma-separated tablet-filters list; combining a full-range filter with an explicit shard of the same keyspace; generated config scripts appending filters programmatically.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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