apache/druid · error · IllegalStateException
Cannot reorder[ ] scan data right now
Error message
Cannot reorder[%s] scan data right now
What it means
LazilyDecoratedRowsAndColumns.materialize() can apply intervals, filters, limits, and virtual columns lazily, but re-ordering scan data is not implemented. If an ordering decoration is set when materialization happens, Druid throws ISE. This is a not-yet-implemented capability, not a data problem.
Solutions
- Remove the ordering requirement from the scan at this pipeline stage
- Sort explicitly after materialization instead of relying on scan ordering
- Use a cursor/scan path that supports ordering directly rather than the decorated wrapper
Defensive patterns
Strategy: try-catch
Validate before calling
if (decoration.getOrdering() != null) {
throw new IllegalStateException("ordering unsupported on LazilyDecoratedRowsAndColumns; sort explicitly");
} Try / catch
try {
rows = lazilyDecorated.materialize();
} catch (IllegalStateException e) {
if (e.getMessage().startsWith("Cannot reorder")) {
rows = sortExplicitly(lazilyDecorated);
} else throw e;
} Prevention
- Don't set ordering on scan decorations unless the downstream path supports it
- Sort after materialization with an explicit sort operator
When it happens
Trigger: A scan-backed RowsAndColumns decorated with a non-null ordering is materialized (via thePair) before the ordering can be honored.
Common situations: Query or downstream operator requests ordered scan output through the lazily decorated wrapper; internal pipeline stages requesting ordering that only a full re-sort could satisfy.
Related errors
- Cannot apply virtual columns
- Cannot order by a non-numeric aggregator
- Could not find the dimension spec for ordering column
- Not implemented
- Null cursor factory found. Probably trying to issue a query…
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/f6a7f7d0fd1e1bd3.
Report an issue: GitHub.
Appendix: source
Thrown at processing/src/main/java/org/apache/druid/query/rowsandcols/LazilyDecoratedRowsAndColumns.java:182
if (needsMaterialization()) {
final Pair<byte[], RowSignature> thePair = materialize();
if (thePair == null) {
reset(new EmptyRowsAndColumns());
} else {
reset(new ColumnBasedFrameRowsAndColumns(Frame.wrap(thePair.lhs), thePair.rhs));
}
}
}
private boolean needsMaterialization()
{
return interval != null || filter != null || limit.isPresent() || ordering != null || virtualColumns != null;
}
private Pair<byte[], RowSignature> materialize()
{
if (ordering != null) {
throw new ISE("Cannot reorder[%s] scan data right now", ordering);
}
final CursorFactory as = base.as(CursorFactory.class);
if (as == null) {
return naiveMaterialize(base);
} else {
return materializeCursorFactory(as);
}
}
private void reset(RowsAndColumns rac)
{
base = rac;
interval = null;
filter = null;
virtualColumns = null;
limit = OffsetLimit.NONE;
viewableColumns = null;View on GitHub (pinned to 9b90983fd2)