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
- Check the wrapped inner error for object-store vs index corruption.
- Delete stale index-header cache files and let store-gateway re-sync blocks.
- Retry the query; transient storage failures resolve on retry.
- 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
- Use exact matchers where possible instead of regex
- Keep index-header caches healthy; reload on corruption alerts
- Handle absent labels gracefully in query layer
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)