thanos-io/thanos · error

frontend.cache-queryable-samples-stats may only be enabled…

Error message

frontend.cache-queryable-samples-stats may only be enabled in conjunction with querier.per-step-stats-enabled. Please set the latter

What it means

ResultsCacheConfig.Validate refuses the combination of cache-queryable-samples-stats enabled while querier.per-step-stats-enabled is off. Per-step stats must be computed by the querier for them to be cacheable, so the frontend feature depends on the querier flag.

Solutions

  1. Also set -querier.per-step-stats-enabled=true on all queriers
  2. Or disable -querier.cache-queryable-samples-stats
  3. Ensure both flags are set consistently across frontend and querier configs

Example fix

# before
querier:
  cache-queryable-samples-stats: true
# after
querier:
  cache-queryable-samples-stats: true
  per-step-stats-enabled: true
Defensive patterns

Strategy: validation

Validate before calling

if cacheQueryableSamplesStats && !perStepStatsEnabled {
	return errors.New("enable querier.per-step-stats-enabled first")
}

Try / catch

if err := cfg.Validate(qCfg); err != nil {
	if strings.Contains(err.Error(), "per-step-stats-enabled") {
		log.Warn("falling back: cache-queryable-samples-stats disabled")
		cfg.CacheQueryableSamplesStats = false
	}
}

Prevention

When it happens

Trigger: Starting Cortex with `-querier.cache-queryable-samples-stats=true` (or yaml `cache_queryable_samples_stats`) while `-querier.per-step-stats-enabled` is false.

Common situations: Operators enabling per-query stats caching for Grafana without also enabling per-step stats on queriers; split querier/frontend deployments where the two flags are configured on different components.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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

Appendix: source

Thrown at internal/cortex/querier/queryrange/results_cache.go:75

// RegisterFlags registers flags.
func (cfg *ResultsCacheConfig) RegisterFlags(f *flag.FlagSet) {
	cfg.CacheConfig.RegisterFlagsWithPrefix("frontend.", "", f)

	f.StringVar(&cfg.Compression, "frontend.compression", "", "Use compression in results cache. Supported values are: 'snappy' and '' (disable compression).")
	f.BoolVar(&cfg.CacheQueryableSamplesStats, "frontend.cache-queryable-samples-stats", false, "Cache Statistics queryable samples on results cache.")
}

func (cfg *ResultsCacheConfig) Validate(qCfg querier.Config) error {
	switch cfg.Compression {
	case "snappy", "":
		// valid
	default:
		return errors.Errorf("unsupported compression type: %s", cfg.Compression)
	}

	if cfg.CacheQueryableSamplesStats && !qCfg.EnablePerStepStats {
		return errors.New("frontend.cache-queryable-samples-stats may only be enabled in conjunction with querier.per-step-stats-enabled. Please set the latter")
	}

	return cfg.CacheConfig.Validate()
}

// Extractor is used by the cache to extract a subset of a response from a cache entry.
type Extractor interface {
	// Extract extracts a subset of a response from the `start` and `end` timestamps in milliseconds in the `from` response.
	Extract(start, end int64, from Response) Response
	ExtractForStep(start, end, step int64, from Response) Response
	ResponseWithoutHeaders(resp Response) Response
	ResponseWithoutStats(resp Response) Response
}

// PrometheusResponseExtractor helps extracting specific info from Query Response.
type PrometheusResponseExtractor struct{}

// Extract extracts response for specific a range from a response.

View on GitHub (pinned to 35b8b99117)