SigNoz/signoz · error

unsupported reduce operator

Error message

unsupported reduce operator

What it means

ReduceToQuery in the v3 traces builder maps the requested reduce operator to a ClickHouse aggregate (avg/max/min/sum/rate etc.). Any reduce operator outside the switch's known cases returns this error, meaning the frontend requested a reduction the traces builder cannot express.

Source

Thrown at pkg/query-service/app/traces/v3/query_builder.go:340

	return strings.Join(having, " AND ")
}

func ReduceToQuery(query string, reduceTo v3.ReduceToOperator, _ v3.AggregateOperator) (string, error) {

	var groupBy string
	switch reduceTo {
	case v3.ReduceToOperatorLast:
		query = fmt.Sprintf("SELECT anyLast(value) as value, now() as ts FROM (%s) %s", query, groupBy)
	case v3.ReduceToOperatorSum:
		query = fmt.Sprintf("SELECT sum(value) as value, now() as ts FROM (%s) %s", query, groupBy)
	case v3.ReduceToOperatorAvg:
		query = fmt.Sprintf("SELECT avg(value) as value, now() as ts FROM (%s) %s", query, groupBy)
	case v3.ReduceToOperatorMax:
		query = fmt.Sprintf("SELECT max(value) as value, now() as ts FROM (%s) %s", query, groupBy)
	case v3.ReduceToOperatorMin:
		query = fmt.Sprintf("SELECT min(value) as value, now() as ts FROM (%s) %s", query, groupBy)
	default:
		return "", fmt.Errorf("unsupported reduce operator")
	}
	return query, nil
}

func AddLimitToQuery(query string, limit uint64) string {
	if limit == 0 {
		limit = 100
	}
	return fmt.Sprintf("%s LIMIT %d", query, limit)
}

func AddOffsetToQuery(query string, offset uint64) string {
	return fmt.Sprintf("%s OFFSET %d", query, offset)
}

// PrepareTracesQuery returns the query string for traces
// start and end are in epoch millisecond
// step is in seconds

View on GitHub (pinned to 5069bf80b0)

Solutions

  1. Use one of the supported reduce operators (avg, max, min, sum, rate, sum_rate, avg_rate, rate_sum, rate_avg, count, count_rate (check switch cases))
  2. If a quantile is needed, compute it via a custom ClickHouse query
  3. Align query-service and frontend versions so unsupported reduce operators are not offered

Example fix

// before
mq.ReduceTo = v3.ReduceToOperatorP90

// after
mq.ReduceTo = v3.ReduceToOperatorAvg
Defensive patterns

Strategy: validation

Validate before calling

var supportedReduces = map[v3.ReduceToOperator]bool{v3.ReduceToOperatorAvg:true, v3.ReduceToOperatorMax:true, v3.ReduceToOperatorMin:true}
if !supportedReduces[mq.ReduceTo] {
    return fmt.Errorf("unsupported reduce operator %s", mq.ReduceTo)
}

Type guard

func isSupportedReduce(op v3.ReduceToOperator) bool {
    switch op {
    case v3.ReduceToOperatorAvg, v3.ReduceToOperatorMax, v3.ReduceToOperatorMin:
        return true
    }
    return false
}

Prevention

When it happens

Trigger: Setting BuilderQuery.ReduceTo to a value like p90, count, or an empty string in a traces query that goes through PrepareTracesQuery.

Common situations: Custom panels or API calls copying metric query configurations (which support more reduce functions like quantiles) onto trace data sources; version skew where newer reduce operators are sent to an older query-service.

Related errors


AI-assisted analysis of SigNoz/signoz@5069bf80b0 (2026-08-28). Data as JSON: /api/errors/7c915ab60b7445ec. Report an issue: GitHub.