thanos-io/thanos · warning

Query fallback to prometheus engine; not analyzable.

Error message

Query fallback to prometheus engine; not analyzable.

What it means

When the query does not implement ExplainableQuery (the query fell back to the plain Prometheus engine) and the requested engine was 'thanos', analyzeQueryOutput returns this warning indicating the analysis is unavailable because of the fallback. The query itself still executes; only the analysis telemetry is missing.

Solutions

  1. Check query-frontend/gateway logs for why the Thanos engine fell back and fix the underlying cause.
  2. Ensure the Thanos engine is enabled/healthy so the query does not fall back.
  3. Treat it as a soft warning: the query results are still valid, only analysis is absent.
Defensive patterns

Strategy: fallback

Try / catch

const body = await res.json();
if (body.status === 'error' && /fallback to prometheus engine/.test(body.error)) {
  // results may still be present; degrade analysis UI and alert on fallback frequency
}

Prevention

When it happens

Trigger: query/queryRange with analyze enabled while the Thanos engine fell back to the Prometheus engine (e.g. Thanos engine unavailable or query unsupported by the Thanos engine).

Common situations: Thanos engine disabled at startup or failing to initialize; operators requesting analysis on queries the Thanos engine cannot execute; feature-flag rollouts mid-migration.

Related errors


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

Appendix: source

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

	return nil, &api.ApiError{Typ: api.ErrorBadData, Err: errors.Errorf("Query not explainable")}
}

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,

View on GitHub (pinned to 35b8b99117)