apache/skywalking · error · IllegalExpressionException
Series No Labeled, left or right result is empty.
Error message
Series No Labeled, left or right result is empty.
What it means
Thrown by LROp.seriesNoLabeled when two non-labeled TIME_SERIES_VALUES operands are combined: if either side's results list is completely empty there is nothing to align, so the operation aborts. Only the first MQEValues of each side is used (series are expected to be single-series).
Source
Thrown at oap-server/mqe-rt/src/main/java/org/apache/skywalking/mqe/rt/operation/LROp.java:211
singleResult.getResults()
.get(0)
.getValues()
.get(0)
.getDoubleValue(),
mqeValue.getDoubleValue(), opType
);
mqeValue.setDoubleValue(newValue);
}
}
}
return manyResult;
}
private static ExpressionResult seriesNoLabeled(ExpressionResult seriesLeft,
ExpressionResult seriesRight,
int opType, LROp calculate) throws IllegalExpressionException {
if (seriesLeft.getResults().isEmpty() || seriesRight.getResults().isEmpty()) {
throw new IllegalExpressionException("Series No Labeled, left or right result is empty.");
}
MQEValues mqeValuesL = seriesLeft.getResults().get(0);
MQEValues mqeValuesR = seriesRight.getResults().get(0);
if (mqeValuesL.getValues().size() != mqeValuesR.getValues().size()) {
throw new IllegalExpressionException("Series No Labeled, left and right series value size not equal.");
}
for (int i = 0; i < mqeValuesL.getValues().size(); i++) {
//clean metric info
MQEValue valueL = mqeValuesL.getValues().get(i);
MQEValue valueR = mqeValuesR.getValues().get(i);
if (valueL.isEmptyValue() || valueR.isEmptyValue()) {
valueL.setEmptyValue(true);
continue;
}
//time should be mapped
double newValue = calculate.apply(valueL.getDoubleValue(), valueR.getDoubleValue(), opType);
mqeValuesL.getValues().get(i).setDoubleValue(newValue);
}View on GitHub (pinned to 102af09b4a)
Solutions
- Run each series operand alone to confirm both return data in the same time range
- Align the time range and step of both metrics — same duration and step produces comparable point counts
- If empty series are expected, use viewAsSeq or isPresent-based logic instead of a plain binary op
- Verify the metric names exist and data is actually being ingested (check UI or raw metric query)
Example fix
// before query: metric_old + metric_new // metric_old has no data in range // after query: viewAsSeq(metric_old, metric_new) // or narrow the range to where both have data
Defensive patterns
Strategy: validation
Validate before calling
ExpressionResult l = mqeService.eval(leftExpr), r = mqeService.eval(rightExpr); boolean ok = !l.getResults().isEmpty() && !r.getResults().isEmpty();
Try / catch
catch (IllegalExpressionException e) { /* check data presence in range first */ } Prevention
- Confirm both series have data in the same time range before combining
- Use viewAsSeq when either series may legitimately be empty
When it happens
Trigger: MQE expression 'seriesA + seriesB' where seriesA or seriesB returned zero results (no data points / no series at all) in the queried time range. Reached from seriesBinaryOp when neither side isLabeledResult().
Common situations: One of the metrics has no data in the selected time window (e.g. service deployed recently, metrics dropped after OAP restart with empty storage); typo'd metric name that resolves to a type but returns nothing; querying a time range before the metric existed; storage (BanyanDB/ES) retention having evicted the data.
Related errors
- Single to Single, left result is empty or has more than one
- Single to Single, right result is empty or has more than one
- Single Labeled to Single Labeled, left labeled result is emp
- Single Labeled to Single Labeled, right labeled result has m
- Many to One, single result is empty or has more than one val
AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14).
Data as JSON: /api/errors/557dd9c7d5f3b254.
Report an issue: GitHub.