apache/skywalking · error · IllegalExpressionException
Unsupported aggregation operation.
Error message
Unsupported aggregation operation.
What it means
IllegalExpressionException from AggregationOp's dispatch switch: the aggregation token applied to an expression is not one of AVG, COUNT, LATEST, MAX, MIN or SUM. The grammar tokenized successfully but the runtime has no implementation for it, so evaluation is refused.
Source
Thrown at oap-server/mqe-rt/src/main/java/org/apache/skywalking/mqe/rt/operation/AggregationOp.java:79
.max(Comparator.comparingDouble(
MQEValue::getDoubleValue)));
case MQEParser.MIN:
return selectResult(result, mqeValues -> mqeValues.getValues()
.stream()
.filter(mqeValue -> !mqeValue.isEmptyValue())
.min(Comparator.comparingDouble(
MQEValue::getDoubleValue)));
case MQEParser.SUM:
return aggregateResult(result, mqeValues -> OptionalDouble.of(mqeValues.getValues()
.stream()
.filter(
mqeValue -> !mqeValue.isEmptyValue())
.flatMapToDouble(
mqeValue -> DoubleStream.of(
mqeValue.getDoubleValue()))
.sum()));
default:
throw new IllegalExpressionException("Unsupported aggregation operation.");
}
}
private static ExpressionResult aggregateResult(ExpressionResult result,
Function<MQEValues, OptionalDouble> aggregator) {
for (MQEValues resultValues : result.getResults()) {
OptionalDouble resultValue = aggregator.apply(resultValues);
List<MQEValue> mqeValueList = new ArrayList<>(1);
//no id
MQEValue mqeValue = new MQEValue();
if (resultValue.isPresent()) {
mqeValue.setEmptyValue(false);
mqeValue.setDoubleValue(resultValue.getAsDouble());
} else {
mqeValue.setEmptyValue(true);
}
mqeValueList.add(mqeValue);
resultValues.setValues(mqeValueList);View on GitHub (pinned to 102af09b4a)
Solutions
- Swap the function for a supported one: AVG, COUNT, LATEST, MAX, MIN, or SUM
- Check the MQE docs for the deployed OAP version and use only listed aggregations
- If UI/OAP versions are mixed, align them (skywalking-ui submodule version vs OAP release)
- For percentile needs, use the dedicated percentile syntax (metric.p99(dt5m)) instead of an aggregation function
Example fix
# before median(service_resp_time.sum(dt5m)) # after service_resp_time.p99(dt5m)
Defensive patterns
Strategy: validation
Validate before calling
private static final Set<String> AGGREGATIONS = Set.of("AVG", "COUNT", "LATEST", "MAX", "MIN", "SUM");
void assertAggregation(String f) {
if (!AGGREGATIONS.contains(f.toUpperCase(Locale.ROOT))) throw new IllegalArgumentException("Unsupported aggregation: " + f);
} Type guard
boolean isSupportedAggregation(String f) {
return f != null && java.util.Set.of("AVG","COUNT","LATEST","MAX","MIN","SUM").contains(f.toUpperCase(Locale.ROOT));
} Prevention
- Use only documented aggregations for your OAP version
- Use percentile syntax metric.pNN(dt) instead of aggregation functions for percentiles
- Keep UI and OAP versions aligned
When it happens
Trigger: Any aggregation function name in an MQE expression outside the implemented set — e.g. 'median(...)', 'stddev(...)', 'rate(...)' used where an aggregation is expected, or a token produced by grammar/runtime version drift between UI and OAP.
Common situations: UI from a newer SkyWalking version emitting an aggregation the older OAP backend lacks; users porting PromQL aggregations (quantile, stddev) into MQE; typos in function names that still lex as identifiers.
Related errors
- Unsupported aggregateLabels function.
- LATEST can only be used in time series result.
- Unsupported binary operation: {}
- Unsupported bool operation: {}
- Unsupported compare operation: {}
AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14).
Data as JSON: /api/errors/e35348e5946d1b73.
Report an issue: GitHub.