vitessio/vitess · error
malformed spec: doesn't define a range: %q
Error message
malformed spec: doesn't define a range: %q
What it means
ParseShardingSpec splits a sharding spec like '00-80,80-' on '-' to build KeyRanges. A single-part spec is only allowed if it is exactly "0" (meaning the full range); any other token without a dash cannot define a range and yields this error. It is a configuration-format validation error on the sharding spec string.
Source
Thrown at go/vt/key/key.go:287
return true
}
return false
}
// ParseShardingSpec parses a string that describes a sharding
// specification. a-b-c-d will be parsed as a-b, b-c, c-d. The empty
// string may serve both as the start and end of the keyspace: -a-b-
// will be parsed as start-a, a-b, b-end.
// "0" is treated as "-", to allow us to not have to special-case
// client code.
func ParseShardingSpec(spec string) ([]*topodatapb.KeyRange, error) {
parts := strings.Split(spec, "-")
if len(parts) == 1 {
if spec == "0" {
parts = []string{"", ""}
} else {
return nil, fmt.Errorf("malformed spec: doesn't define a range: %q", spec)
}
}
old := parts[0]
ranges := make([]*topodatapb.KeyRange, len(parts)-1)
for i, p := range parts[1:] {
if p == "" && i != (len(parts)-2) {
return nil, fmt.Errorf("malformed spec: MinKey/MaxKey cannot be in the middle of the spec: %q", spec)
}
if p != "" && p <= old {
return nil, fmt.Errorf("malformed spec: shard limits should be in order: %q", spec)
}
s, err := hex.DecodeString(old)
if err != nil {
return nil, err
}
if len(s) == 0 {
s = nilView on GitHub (pinned to 01a25a7d17)
Solutions
- Rewrite the spec as a proper range 'start-end' (e.g. "0" or "00-80,80-")
- If you meant the full keyspace range, use the spec "0" exactly
- Check for copy/paste truncation that dropped the '-<end>' half of the range
Example fix
// before
key.ParseShardingSpec("80") // error
// after
key.ParseShardingSpec("80-") // range from 80 to the end
key.ParseShardingSpec("00-80") Defensive patterns
Strategy: validation
Validate before calling
func validShardingSpec(spec string) error {
if spec == "0" { return nil }
for _, part := range strings.Split(spec, ",") {
if !strings.Contains(part, "-") {
return fmt.Errorf("sharding spec part %q must be a range 'start-end'", part)
}
}
return nil
} Try / catch
krs, err := key.ParseShardingSpec(spec)
if err != nil {
return fmt.Errorf("bad sharding spec %q: %w", spec, err)
} Prevention
- Validate sharding specs at config-load time, before topo writes
- Remember the only valid single-token spec is "0"; everything else needs 'start-end'
- Lint config files for specs that lost their '-' during templating or copy/paste
When it happens
Trigger: Calling ParseShardingSpec (directly or via initShardArray) with a spec string containing no '-' and not equal to "0" — e.g. "80", "abc", or an empty/whitespace spec.
Common situations: Typos in sharding specs in topo/config files (missing the second boundary, e.g. "00" instead of "00-80"); pasting a single keyspace id instead of a range; users unaware that only "0" is the valid one-token form.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- either source or target shards are missing
- error parsing shard name %v: %v
- malformed spec: MinKey/MaxKey cannot be in the middle of the
- malformed spec: shard limits should be in order: %q
- conflicting entries: %q overlaps with %q
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/57a84792b67d6df9.
Report an issue: GitHub.