SigNoz/signoz · error
unsupported aggregate operator %s
Error message
unsupported aggregate operator %s
What it means
The aggregation switch in buildTracesQuery (v4) handles a fixed set of aggregate operators (count, count_distinct, rate/sum/avg variants, etc.); anything else falls to default and is rejected. This is the last-resort guard for aggregate operators that passed earlier panel-type checks.
Source
Thrown at pkg/query-service/app/traces/v4/query_builder.go:457
subQuery, err := existsSubQueryForFixedColumn(mq.AggregateAttribute, v3.FilterOperatorExists)
if err == nil {
filterSubQuery = fmt.Sprintf("%s AND %s", filterSubQuery, subQuery)
}
} else {
cType := getClickHouseTracesColumnType(mq.AggregateAttribute.Type)
cDataType := getClickHouseTracesColumnDataType(mq.AggregateAttribute.DataType)
filterSubQuery = fmt.Sprintf("%s AND mapContains(%s_%s, '%s')", filterSubQuery, cType, cDataType, mq.AggregateAttribute.Key)
}
}
op := "toFloat64(count())"
query := fmt.Sprintf(queryTmpl, op, filterSubQuery, groupBy, having, orderBy)
return query, nil
case v3.AggregateOperatorCountDistinct:
op := fmt.Sprintf("toFloat64(count(distinct(%s)))", aggregationKey)
query := fmt.Sprintf(queryTmpl, op, filterSubQuery, groupBy, having, orderBy)
return query, nil
default:
return "", fmt.Errorf("unsupported aggregate operator %s", mq.AggregateOperator)
}
}
// PrepareTracesQuery returns the query string for traces
// start and end are in epoch millisecond
// step is in seconds
func PrepareTracesQuery(start, end int64, panelType v3.PanelType, mq *v3.BuilderQuery, options v3.QBOptions) (string, error) {
// adjust the start and end time to the step interval
if panelType == v3.PanelTypeGraph {
// adjust the start and end time to the step interval for graph panel types
start = start - (start % (mq.StepInterval * 1000))
end = end - (end % (mq.StepInterval * 1000))
}
if options.GraphLimitQtype == constants.FirstQueryGraphLimit {
// give me just the group by names
query, err := buildTracesQuery(start, end, mq.StepInterval, mq, panelType, options)
if err != nil {
return "", errView on GitHub (pinned to 5069bf80b0)
Solutions
- Use a supported traces aggregate operator (count, count_distinct, sum, avg, min, max, rate variants, etc.)
- Compute quantiles via a ClickHouse query builder expression instead
- Align frontend and query-service versions
Example fix
// before mq.AggregateOperator = "p95" // after mq.AggregateOperator = v3.AggregateOperatorAvg
Defensive patterns
Strategy: validation
Validate before calling
var supportedAggs = map[v3.AggregateOperator]bool{v3.AggregateOperatorCount: true, v3.AggregateOperatorCountDistinct: true /* etc. */}
if !supportedAggs[mq.AggregateOperator] {
return fmt.Errorf("aggregate %s unsupported for traces", mq.AggregateOperator)
} Type guard
func isTraceAggregate(op v3.AggregateOperator) bool {
switch op {
case v3.AggregateOperatorCount, v3.AggregateOperatorCountDistinct:
return true
}
return false
} Prevention
- Restrict traces UI to implemented aggregate operators
- Smoke-test custom dashboards against the deployed query-service version
When it happens
Trigger: Setting mq.AggregateOperator to an operator not implemented in the v4 traces aggregation switch (e.g. quantiles like p95, or an empty string) on a non-no-op traces query.
Common situations: Frontends exposing the full metrics operator set (including quantiles) for traces; custom clients sending arbitrary operator strings; version mismatch where newer operators aren't implemented server-side.
Related errors
- unsupported operator %s
- unsupported aggregate operator %s for panelType %s
- unsupported operator %s
- unsupported operation, exists and not exists can only be app
- invalid value for key %s: %v
AI-assisted analysis of SigNoz/signoz@5069bf80b0 (2026-08-28).
Data as JSON: /api/errors/4c629b37278d9bee.
Report an issue: GitHub.