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

  1. Inspect the PromQL selectors used and restrict them to =, !=, =~, !~ matchers.
  2. Upgrade Thanos/store so it knows any newer matcher types.
  3. 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

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


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)