thanos-io/thanos · error
parser ParseMetricSelector
Error message
parser ParseMetricSelector
What it means
After proxying, the handler parses every MatcherString in the request as a PromQL metric selector via extpromql.ParseMetricSelector; a parse failure is wrapped as 'parser ParseMetricSelector'. It means one of the requested matcher strings is not a valid metric selector like {job="foo",env=~"prod.*"}.
Solutions
- Validate each matcher string with promql.ParseMetricSelector client-side before calling the API
- Fix malformed selectors (balanced braces, quoted values, valid matchers =,!=,=~,!~)
- Use the SDK/helper to construct matcher sets programmatically instead of string concatenation
Example fix
// before
req.MatcherString = []string{"{job=prod}"} // invalid: unquoted value
// after
req.MatcherString = []string{"{job=\"prod\"}"} Defensive patterns
Strategy: validation
Validate before calling
for _, s := range matchers {
if _, err := promql.ParseMetricSelector(s); err != nil {
return fmt.Errorf("invalid matcher %q: %w", s, err)
}
} Type guard
func isValidMetricSelector(s string) bool {
_, err := extpromql.ParseMetricSelector(s)
return err == nil
} Prevention
- Build matchers programmatically via labels.ParseMatcher instead of string concat
- Quote braces and values carefully when passing selectors through shells
- Test matcher strings with a parser before sending
When it happens
Trigger: Calling the Rules API with req.MatcherString entries that are empty strings or not parseable PromQL selectors (unbalanced braces, invalid label matchers, bad regex).
Common situations: Hand-built matcher strings from user input; shell quoting stripping braces or quotes; passing label names or LogQL instead of PromQL selectors; upgrading promql parser versions that reject previously tolerated syntax.
Understand the failure class
Background: "Invalid query parameter" / "Failed to parse value of ...": fixing bad query string parameters across APIs — this error's family across 36 libraries.
Related errors
- Invalid time value for
- cannot parse to a valid timestamp
- parse metric selector
- failed to parse config size from metadata
- failed to parser config version
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/1b5c068e6146ae21.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/rules/rules.go:69
return c
}
func (rr *GRPCClient) Rules(ctx context.Context, req *rulespb.RulesRequest) (*rulespb.RuleGroups, annotations.Annotations, error) {
span, ctx := tracing.StartSpan(ctx, "rules_request")
defer span.Finish()
resp := &rulesServer{ctx: ctx}
if err := rr.proxy.Rules(req, resp); err != nil {
return nil, nil, errors.Wrap(err, "proxy Rules")
}
var err error
matcherSets := make([][]*labels.Matcher, len(req.MatcherString))
for i, s := range req.MatcherString {
matcherSets[i], err = extpromql.ParseMetricSelector(s)
if err != nil {
return nil, nil, errors.Wrap(err, "parser ParseMetricSelector")
}
}
resp.groups = filterRulesByMatchers(resp.groups, matcherSets)
resp.groups = filterRulesByNamesAndFile(resp.groups, req.RuleName, req.RuleGroup, req.File)
// TODO(bwplotka): Move to SortInterface with equal method and heap.
resp.groups = dedupGroups(resp.groups)
for _, g := range resp.groups {
g.Rules = dedupRules(g.Rules, rr.replicaLabels)
}
return &rulespb.RuleGroups{Groups: resp.groups}, resp.warnings, nil
}
// filters rules by group name, rule name or file.
func filterRulesByNamesAndFile(ruleGroups []*rulespb.RuleGroup, ruleName []string, ruleGroup []string, file []string) []*rulespb.RuleGroup {
if len(ruleName) == 0 && len(ruleGroup) == 0 && len(file) == 0 {View on GitHub (pinned to 35b8b99117)