apache/druid · error · IllegalStateException

Row [%d] out of bounds

Error message

Row [%d] out of bounds

What it means

isSameKeyAsMark validates that the row being compared lies inside the frame's row range. If markFrame is unset or the row index is negative or >= holder.frame.numRows(), an IllegalStateException('Row [%d] out of bounds') is thrown, indicating the merge-join logic attempted to compare a row that does not exist — an internal invariant breach rather than a data or user error.

Source

Thrown at multi-stage-query/src/main/java/org/apache/druid/msq/querykit/common/SortMergeJoinFrameProcessor.java:837

    public void clear()
    {
      holders.clear();
      markFrame = -1;
      markRow = -1;
      currentFrame = -1;
    }

    /**
     * Whether the provided frame and row compares equally to the mark row. The provided row must be at, or after,
     * the mark row.
     */
    private boolean isSameKeyAsMark(final FrameHolder holder, final int row)
    {
      if (markFrame < 0) {
        throw new ISE("No marked frame");
      }
      if (row < 0 || row >= holder.frame.numRows()) {
        throw new ISE("Row [%d] out of bounds", row);
      }

      final FrameHolder markHolder = holders.get(markFrame);
      final int cmp = markHolder.comparisonWidget.compare(markRow, holder.comparisonWidget, row);

      if (cmp > 0) {
        // The provided row is at, or after, the marked row.
        // Therefore, cmp > 0 may indicate that input was provided out of order.
        throw new ISE("Row compares higher than mark; out-of-order input?");
      }

      return cmp == 0;
    }
  }

  /**
   * Selector for joined rows. This is used as an input to {@link #frameWriter}.
   */

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Retry the query; if reproducible, file a Druid bug including the query and stack trace
  2. Adjust frame/row batch sizing context parameters as a workaround to shift frame boundaries
  3. Reduce join input sizes (filter, pre-aggregate) to avoid the failing boundary condition
  4. Check for a newer Druid version with fixes to SortMergeJoinFrameProcessor
Defensive patterns

Strategy: retry

Try / catch

try {
  runMsqQuery(query);
} catch (IllegalStateException | MSQException e) {
  if (e.getMessage() != null && e.getMessage().contains("out of bounds")) {
    // engine bug: retry once, then collect query/trace and report to Druid
  }
}

Prevention

When it happens

Trigger: Internal: during hasCompleteSetForMark or isCurrentSameKeyAsMark, the processor passes a row index outside the current frame holder (cursor bookkeeping desync, e.g. after a frame flush or boundary miscount).

Common situations: Rarely user-caused; surfaces as an engine bug in sort-merge join cursor management, potentially reproducible with particular frame-boundary sizes and join key orderings; report to Druid with the query.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/15a386ebf1dd3fdd. Report an issue: GitHub.