thanos-io/thanos · error
unrecognized matcher type
Error message
unrecognized matcher type
What it means
PrometheusStore.Series converts labels matchers to Prometheus remote-read matcher types. If a matcher implements labels.Matcher but its Type() is not EQ/NEQ/RE/NRE, the switch hits default and returns 'unrecognized matcher type'. This guards against unsupported or future matcher kinds.
Solutions
- Inspect the PromQL selectors used and restrict them to =, !=, =~, !~ matchers.
- Upgrade Thanos/store so it knows any newer matcher types.
- Audit custom code that constructs labels.Matcher values directly.
Example fix
// before
matcher := labels.MustNewMatcher(labels.MatchType("like"), "job", "foo") // invalid
// after
matcher := labels.MustNewMatcher(labels.MatchRegexp, "job", "foo") Defensive patterns
Strategy: validation
Validate before calling
valid := []labels.MatchType{labels.MatchEqual, labels.MatchNotEqual, labels.MatchRegexp, labels.MatchNotRegexp}
for _, m := range matchers {
if !slices.Contains(valid, m.Type) {
return fmt.Errorf("matcher %q has unsupported type %q", m.Name, m.Type)
}
} Try / catch
if err := s.Series(ctx, req); err != nil {
if strings.Contains(err.Error(), "unrecognized matcher type") {
// rewrite/strip the offending selector client-side and retry
}
return err
} Prevention
- Only issue =, !=, =~, !~ selectors against remote read stores.
- Keep client PromQL libraries and Thanos versions aligned.
- Validate user-supplied selectors before dispatching store queries.
When it happens
Trigger: Building a Series query whose selectors include a matcher type outside the four mapped ones (e.g. a custom MatchType implementation or newly added upstream match type).
Common situations: Client libraries or instrumentation adding new matcher types; custom code constructing labels.Matcher with an out-of-range MatchType; version skew where a newer PromQL feature is sent to an older Thanos store.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- read query instant response
- error: , type: , warning
- error: , type
- query Prometheus
- not supported remote read content type
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/33f52dd84bee60f9.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/store/prometheus.go:195
shardMatcher := r.ShardInfo.Matcher(&p.buffers)
defer shardMatcher.Close()
q := &prompb.Query{StartTimestampMs: r.MinTime, EndTimestampMs: r.MaxTime}
for _, m := range matchers {
pm := &prompb.LabelMatcher{Name: m.Name, Value: m.Value}
switch m.Type {
case labels.MatchEqual:
pm.Type = prompb.LabelMatcher_EQ
case labels.MatchNotEqual:
pm.Type = prompb.LabelMatcher_NEQ
case labels.MatchRegexp:
pm.Type = prompb.LabelMatcher_RE
case labels.MatchNotRegexp:
pm.Type = prompb.LabelMatcher_NRE
default:
return errors.New("unrecognized matcher type")
}
q.Matchers = append(q.Matchers, pm)
}
queryPrometheusSpan, ctx := tracing.StartSpan(s.Context(), "query_prometheus")
queryPrometheusSpan.SetTag("query.request", q.String())
httpResp, err := p.startPromRemoteRead(ctx, q)
if err != nil {
queryPrometheusSpan.Finish()
return errors.Wrap(err, "query Prometheus")
}
// Negotiate content. We requested streamed chunked response type, but still we need to support old versions of
// remote read.
contentType := httpResp.Header.Get("Content-Type")
if strings.HasPrefix(contentType, "application/x-protobuf") {
return p.handleSampledPrometheusResponse(s, httpResp, queryPrometheusSpan, extLset, enableChunkHashCalculation, extLsetToRemove)View on GitHub (pinned to 35b8b99117)