thanos-io/thanos · error

matchersToPostingGroups

Error message

matchersToPostingGroups

What it means

Inside the bucket series set expansion, r (bucketStoreSeriesSet) converts label matchers into posting groups via matchersToPostingGroups, which consults the index header's LabelValues (and possibly the bucket). Any failure there — bad matcher semantics, index-header read failure, missing label values — is wrapped as 'matchersToPostingGroups'. It represents a failure to translate query matchers into index posting lists.

Solutions

  1. Check the wrapped inner error for object-store vs index corruption.
  2. Delete stale index-header cache files and let store-gateway re-sync blocks.
  3. Retry the query; transient storage failures resolve on retry.
  4. If a specific matcher reliably fails, simplify it (e.g. replace regex with exact match) and inspect the label's presence in the index.
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check matchers against known label names
for _, m := range ms {
	if vals, _ := indexHeader.LabelValues(ctx, m.Name); vals == nil {
		// label absent in this block; skip block early
	}
}

Try / catch

if err != nil {
	if isTransientStorageErr(err) {
		// retry with backoff
	}
	return errors.Wrap(err, "matchersToPostingGroups")
}

Prevention

When it happens

Trigger: matchersToPostingGroups(ctx, r.block.indexHeaderReader.LabelValues, ms) errors: LabelValues lookup fails on the index header, or the lazy-value-loading func hits object storage and fails, or a matcher references a value that cannot be resolved.

Common situations: Corrupt/truncated index-header cache in store-gateway, object storage errors while resolving lazy label values, regex matchers too exotic triggering index lookups that fail, block partially removed mid-query.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07). Data as JSON: /api/errors/10f386d2b0636b16. Report an issue: GitHub.

Appendix: source

Thrown at pkg/store/bucket.go:2682

	if len(ms) == 0 {
		return nil, nil
	}

	hit, postings, err := r.fetchExpandedPostingsFromCache(ctx, ms, bytesLimiter, tenant)
	if err != nil {
		return nil, err
	}
	if hit {
		return newLazyExpandedPostings(postings), nil
	}
	var (
		allRequested = false
		hasAdds      = false
	)

	postingGroups, err := matchersToPostingGroups(ctx, r.block.indexHeaderReader.LabelValues, ms)
	if err != nil {
		return nil, errors.Wrap(err, "matchersToPostingGroups")
	}
	if postingGroups == nil {
		r.storeExpandedPostingsToCache(ms, index.EmptyPostings(), 0, tenant)
		return nil, nil
	}
	i := 0
	for _, pg := range postingGroups {
		allRequested = allRequested || pg.addAll
		hasAdds = hasAdds || len(pg.addKeys) > 0

		// If a posting group doesn't have any keys, like posting group created
		// from `=~".*"`, we don't have to keep the posting group as long as we
		// keep track of whether we need to add all postings or not.
		if len(pg.addKeys) == 0 && len(pg.removeKeys) == 0 {
			continue
		}
		postingGroups[i] = pg
		i++

View on GitHub (pinned to 35b8b99117)