thanos-io/thanos · info

Query not analyzable; change engine to 'thanos'.

Error message

Query not analyzable; change engine to 'thanos'.

What it means

When the query is not explainable and the requested engine is not 'thanos' (i.e. the user explicitly chose the Prometheus engine), analyzeQueryOutput returns this advisory warning telling the user to switch the engine to 'thanos' to get query analysis. The query results are still returned; only analysis output is unavailable.

Solutions

  1. Add `engine=thanos` to the request when you need analysis output.
  2. Disable the analyze parameter if you intentionally use the Prometheus engine.
  3. Configure clients/dashboards to only request analysis against Thanos-engine endpoints.

Example fix

// before
GET /api/v1/query?query=up&analyze=true&engine=prometheus
// after
GET /api/v1/query?query=up&analyze=true&engine=thanos
Defensive patterns

Strategy: fallback

Validate before calling

if (analyzeRequested && engine !== 'thanos') {
  console.warn('analysis requires engine=thanos; disabling analyze');
  analyzeRequested = false;
}

Try / catch

const body = await res.json();
if (body.status === 'error' && /change engine to 'thanos'/.test(body.error)) {
  // either add engine=thanos or drop the analyze param and retry
}

Prevention

When it happens

Trigger: query/queryRange with `analyze=true` and `engine=prometheus` (or engine unset while prometheus is the active engine), so the query type lacks Analyze().

Common situations: Users testing analysis with the default Prometheus engine; clients enabling analyze on endpoints configured with engine=prometheus.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at pkg/api/query/v1.go:458

func (qapi *QueryAPI) parseQueryAnalyzeParam(r *http.Request) bool {
	return (r.FormValue(QueryAnalyzeParam) == "true" || r.FormValue(QueryAnalyzeParam) == "1")
}

func analyzeQueryOutput(query promql.Query, engineType PromqlEngineType, tracker *fanout.Tracker) (queryTelemetry, error) {
	if eq, ok := query.(engine.ExplainableQuery); ok {
		if analyze := eq.Analyze(); analyze != nil {
			return processAnalysis(analyze, tracker), nil
		} else {
			return queryTelemetry{}, errors.Errorf("Query: %v not analyzable", query)
		}
	}

	var warning error
	if engineType == PromqlEngineThanos {
		warning = errors.New("Query fallback to prometheus engine; not analyzable.")
	} else {
		warning = errors.New("Query not analyzable; change engine to 'thanos'.")
	}

	return queryTelemetry{}, warning
}

func processAnalysis(a *engine.AnalyzeOutputNode, tracker *fanout.Tracker) queryTelemetry {
	var analysis queryTelemetry
	analysis.OperatorName = a.OperatorTelemetry.String()
	analysis.Execution = a.OperatorTelemetry.ExecutionTimeTaken().String()
	analysis.PeakSamples = a.PeakSamples()
	analysis.TotalSamples = a.TotalSamples()
	if stores := tracker.Get(a.OperatorID); len(stores) > 0 {
		analysis.Fanout = make([]fanoutEntry, 0, len(stores))
		for _, s := range stores {
			analysis.Fanout = append(analysis.Fanout, fanoutEntry{
				EndpointAddr:   s.EndpointAddr,
				Duration:       s.Duration.String(),
				BytesProcessed: s.BytesProcessed,

View on GitHub (pinned to 35b8b99117)