vitessio/vitess · error

invalid FilterByShard parameter: %v

Error message

invalid FilterByShard parameter: %v

What it means

NewFilterByShard parses each filter entry by splitting on '|'. An entry that doesn't yield exactly two parts (keyspace|shard) is rejected with this error. It is the underlying parse error wrapped by the tablet-filters error in NewVTGateHealthCheckFilters.

Source

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

// a keyspace.
type filterShard struct {
	keyspace string
	shard    string
	keyRange *topodatapb.KeyRange // only set if shard is also a KeyRange
	options  Options
}

// NewFilterByShard creates a new FilterByShard for use by a
// TopologyWatcher. Each filter is a keyspace|shard entry, where shard
// can either be a shard name, or a keyrange. All tablets that match
// at least one keyspace|shard tuple will be forwarded by the
// TopologyWatcher to its consumer.
func NewFilterByShard(filters []string, opts ...Option) (*FilterByShard, error) {
	m := make(map[string][]*filterShard)
	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)
			}
		}

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Rewrite the offending entry as exactly 'keyspace|shard', e.g. 'commerce|0' or 'commerce|-'.
  2. Use '-' as the shard name for a single-shard keyspace ('commerce|-').
  3. Check for accidental extra '|' segments (cell-qualified values are not accepted here).
  4. Trim whitespace/empty entries from the tablet-filters list before parsing.

Example fix

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

Strategy: validation

Validate before calling

func validTabletFilter(f string) bool {
	parts := strings.Split(f, "|")
	return len(parts) == 2 && parts[0] != ""
}

Try / catch

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

Prevention

When it happens

Trigger: Calling NewFilterByShard (directly or via NewVTGateHealthCheckFilters) with an entry containing zero or multiple '|' separators — e.g. "commerce", "commerce|0|extra", or an empty string.

Common situations: Using dot or slash separators out of habit ("commerce.0", "commerce/0"); pasting fully-qualified table names or cell|keyspace|shard triples into tablet-filters; whitespace or empty entries in a comma-split list.

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/ec55bb55148b8e1b. Report an issue: GitHub.