thanos-io/thanos · warning

Query: not analyzable

Error message

Query: %v not analyzable

What it means

analyzeQueryOutput returns this error when the query implements ExplainableQuery (i.e. runs on the Thanos engine) but eq.Analyze() returns nil, meaning the engine could not produce an analysis plan for the query. It surfaces as a warning/error on /api/v1/query and /api/v1/query_range when the analyze parameter is set.

Solutions

  1. Retry the query without the analyze parameter to get results without analysis telemetry.
  2. Simplify or reshape the query so the Thanos engine produces a non-nil analysis plan.
  3. Upgrade Thanos; newer engines return an analysis for more query shapes instead of nil.

Example fix

// before
GET /api/v1/query?query=vector(1)&analyze=true
// after
GET /api/v1/query?query=vector(1)
Defensive patterns

Strategy: fallback

Try / catch

const body = await res.json();
if (body.status === 'error' && /not analyzable/.test(body.error)) {
  // retry once without the analyze parameter
  return fetch(urlWithoutAnalyze);
}

Prevention

When it happens

Trigger: Calling query/queryRange with `analyze=true` (or `analyze=1`) on a Thanos-engine query whose Analyze() returns nil, typically for trivial or unsupported query shapes the analyzer cannot represent.

Common situations: Profiled/analyzed dashboards where the query is a constant expression or otherwise has no execution plan nodes; querying with analyze enabled during engine upgrades where analysis is partially supported.

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/2456e98212ef6073. Report an issue: GitHub.

Appendix: source

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

}

func (qapi *QueryAPI) getQueryExplain(query promql.Query) (*engine.ExplainOutputNode, *api.ApiError) {
	if eq, ok := query.(engine.ExplainableQuery); ok {
		return eq.Explain(), nil
	}
	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()

View on GitHub (pinned to 35b8b99117)