apache/druid · error · IllegalArgumentException
orderingsToMerge is empty
Error message
orderingsToMerge is empty
What it means
Metadata.mergeOrderings throws IAE when given an empty list of per-segment orderings to merge. Merging sort-order metadata requires at least one input ordering; with none, no merged OrderBy list can be computed.
Solutions
- Guard the call site and return a default (e.g. Cursors.ascendingTimeOrder) when the list is empty
- Pass a default ordering list for legacy segments instead of an empty list
- Only invoke mergeOrderings when at least one segment supplies ordering metadata
Example fix
// before
List<OrderBy> merged = Metadata.mergeOrderings(orderingsToMerge);
// after
List<OrderBy> merged = orderingsToMerge.isEmpty()
? Collections.singletonList(OrderBy.ascendingTimeOrder())
: Metadata.mergeOrderings(orderingsToMerge); Defensive patterns
Strategy: validation
Validate before calling
if (orderingsToMerge == null || orderingsToMerge.isEmpty()) { return defaultOrdering(); } Try / catch
try { Metadata.mergeOrderings(list); } catch (IAE e) { if (e.getMessage().contains("orderingsToMerge is empty")) { /* use default time-ordering */ } else throw e; } Prevention
- Default legacy/null ordering metadata to ascendingTimeOrder before merging
- Skip mergeOrderings when no segment carries ordering metadata
- Collect metadata across all segments before merging
When it happens
Trigger: Calling Metadata.mergeOrderings(Collections.emptyList()) or mergedOrdering over segments where no segment has ordering metadata (e.g. legacy segments) without defaulting the input lists.
Common situations: Custom tooling reading/merging segment metadata for all-null or legacy segments built before 'ordering' was introduced; compaction code aggregating metadata from empty segment sets.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Index metadata doesn't exist for segment
- A-Not-B requires at least 1 sketch
- Access-Check-Result
- Action [ ] failed for worker [ ] with status ( )
- Actual Row count mismatch. Expected
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/ab68a84f2467a561.
Report an issue: GitHub.
Appendix: source
Thrown at processing/src/main/java/org/apache/druid/segment/Metadata.java:368
", timestampSpec=" + timestampSpec +
", queryGranularity=" + queryGranularity +
", rollup=" + rollup +
", ordering=" + ordering +
", projections=" + projections +
", clusteredBaseTable=" + clusteredBaseTable +
'}';
}
/**
* Merge {@link #getOrdering()} from different metadatas.
*
* When an input sort order is null, we assume it is {@link Cursors#ascendingTimeOrder()}, as this was the only
* sort order possible prior to the introduction of the "ordering" field.
*/
public static List<OrderBy> mergeOrderings(List<List<OrderBy>> orderingsToMerge)
{
if (orderingsToMerge.isEmpty()) {
throw new IAE("orderingsToMerge is empty");
}
final List<OrderBy> mergedOrdering = new ArrayList<>();
while (true) {
final int position = mergedOrdering.size();
OrderBy orderBy = null;
// Iterate through each sort order, check that the columns at "position" are all the same. If not, return
// the mergedOrdering as-is.
for (List<OrderBy> ordering : orderingsToMerge) {
if (ordering == null) {
// null ordering is treated as [__time].
ordering = Cursors.ascendingTimeOrder();
}
if (position < ordering.size()) {
if (orderBy == null) {View on GitHub (pinned to 9b90983fd2)