thanos-io/thanos · error
failed to create matchers cache
Error message
failed to create matchers cache
What it means
runReceive tries to initialize a matchers cache for the store API via storecache.NewMatchersCache when --store.enable-thanos-compressed-response / matcher cache size is set (>0). The error wraps any failure from the cache constructor, most commonly a failure to register the cache's Prometheus metrics with the registry. Receive exits with this error during startup.
Solutions
- Inspect the wrapped cause: enable debug logging and read the underlying error returned by storecache.NewMatchersCache.
- Verify --matcher-cache-size is a sane positive integer (e.g. 10000) and not malformed.
- Ensure the Prometheus registerer passed to runReceive is healthy and does not already have conflicting collectors registered.
- Pin/upgrade Thanos to a version matching your Prometheus client_golang to avoid metric incompatibilities.
- If you do not need caching, omit --matcher-cache-size so the NoopMatchersCache is used.
Example fix
// before thanos receive --matcher-cache-size=0abc // after thanos receive --matcher-cache-size=10000
Defensive patterns
Strategy: validation
Validate before calling
if size, err := strconv.Atoi(flagValue); err != nil || size <= 0 { return fmt.Errorf("--matcher-cache-size must be a positive integer, got %q", flagValue) } Prevention
- Validate flag values before launching receive
- Keep Thanos and Prometheus client library versions aligned
- Register cache metrics only once per registry
- Omit matcher-cache-size if caching is not required
When it happens
Trigger: Starting `thanos receive` with --matcher-cache-size greater than 0 while storecache.NewMatchersCache(WithSize(...), WithPromRegistry(...)) returns an error, e.g. metric registration fails against the provided Prometheus registerer.
Common situations: Passing a huge or negative-derived cache size configuration; a custom/limited Prometheus registry that rejects metric registration; corrupted or conflicting metric collectors already registered.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- get content of limit configuration
- parse limit configuration
- creating limiter
- --receive.lazy-retrieval-max-buffered-responses must be > 0
- failed to validate prometheus flags
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/3b219b7a7a8a5826.
Report an issue: GitHub.
Appendix: source
Thrown at cmd/thanos/receive.go:235
return errors.Wrap(err, "open storage dir")
}
// Create TSDB for the default tenant.
if err := createDefautTenantTSDB(logger, conf.defaultTenantID, dataDir); err != nil {
return errors.Wrapf(err, "create default tenant tsdb in %v", conf.dataDir)
}
}
relabelConfig, err := conf.relabelCfg.RelabelConfig(nil)
if err != nil {
return errors.Wrap(err, "get relabel configuration")
}
var cache = storecache.NoopMatchersCache
if conf.matcherCacheSize > 0 {
cache, err = storecache.NewMatchersCache(storecache.WithSize(conf.matcherCacheSize), storecache.WithPromRegistry(reg))
if err != nil {
return errors.Wrap(err, "failed to create matchers cache")
}
multiTSDBOptions = append(multiTSDBOptions, receive.WithMatchersCache(cache))
}
multiTSDBOptions = append(multiTSDBOptions, receive.WithUploadConcurrency(conf.uploadConcurrency))
dbs := receive.NewMultiTSDB(
dataDir,
logger,
reg,
tsdbOpts,
lset,
conf.tenantLabelName,
bkt,
conf.allowOutOfOrderUpload,
conf.skipCorruptedBlocks,
hashFunc,
multiTSDBOptions...,View on GitHub (pinned to 35b8b99117)