thanos-io/thanos · error
failed to convert matchers
Error message
failed to convert matchers
What it means
The status server converts incoming protobuf storepb.LabelMatchers to Prometheus matchers via storepb.MatchersToPromMatchers before applying external-label filtering. If a matcher's type or value cannot be represented as a Prometheus matcher, the error is wrapped as "failed to convert matchers" and the TSDBStats RPC fails.
Solutions
- Fix the matcher: ensure regex values are valid RE2 (test with a regex validator).
- Use only supported matcher types (EQ, NEQ, RE, NRE) in the request.
- Update the client library to match the server's storepb API version.
- Simplify to exact label matchers ("=" instead of "=~") when regex is unnecessary.
Example fix
// before
matcher: {type: RE, name: "rule", value: "[a-"} // invalid regex
// after
matcher: {type: RE, name: "rule", value: "[a-z]+"} Defensive patterns
Strategy: validation
Validate before calling
// validate matchers client-side before the RPC
re, err := regexp.Compile(m.Value)
if err != nil { return fmt.Errorf("invalid matcher regex %q: %w", m.Value, err) } Type guard
func validMatcher(m storepb.LabelMatcher) bool {
switch m.Type {
case storepb.LabelMatcher_EQ, storepb.LabelMatcher_NEQ:
return true
case storepb.LabelMatcher_RE, storepb.LabelMatcher_NRE:
_, err := regexp.Compile(m.Value)
return err == nil
}
return false
} Prevention
- Compile regex matchers client-side before sending
- Restrict UI/automation to EQ/NEQ/RE/NRE matcher types
- Keep client storepb versions aligned with the server
When it happens
Trigger: Calling the TSDB statistics API with a malformed label matcher: unknown matcher type in the protobuf, invalid regex value (uncompilable RE2), or an otherwise invalid matcher value in the request.
Common situations: Hand-crafted gRPC/API requests with wrong matcher type enums; a client sending a regex matcher with syntactically invalid regex like "[a-"; version mismatch between client storepb API and server.
Related errors
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/798884a382da7fca.
Report an issue: GitHub.
Appendix: source
Thrown at cmd/thanos/rule.go:800
info.WithStatusInfoFunc(),
)
storeServer := store.NewLimitedStoreServer(store.NewInstrumentedStoreServer(reg, tsdbStore), reg, conf.storeRateLimits)
options = append(options, grpcserver.WithServer(store.RegisterStoreServer(storeServer, logger)))
// Add Status server for TSDB statistics
statusSrv := status.NewServer(
component.Rule.String(),
status.WithTSDBStatisticsGetter(
status.TSDBStatisticsGetterFunc(func(limit int, matchers []storepb.LabelMatcher) (map[string]tsdb.Stats, error) {
if !httpProbe.IsReady() {
return nil, errors.New("not ready")
}
// Check if external labels match the provided matchers.
extLabels := conf.lset
promMatchers, err := storepb.MatchersToPromMatchers(matchers...)
if err != nil {
return nil, errors.Wrap(err, "failed to convert matchers")
}
for _, matcher := range promMatchers {
if !matcher.Matches(extLabels.Get(matcher.Name)) {
// External labels don't match, return empty result.
return nil, nil
}
}
stats := tsdbDB.Head().Stats(labels.MetricName, limit)
return map[string]tsdb.Stats{
"": *stats,
}, nil
}),
),
)
options = append(options, grpcserver.WithServer(status.RegisterStatusServer(statusSrv)))
}
View on GitHub (pinned to 35b8b99117)