apache/druid · error · IllegalArgumentException

startFrame[%,d] > endFrame[%,d]

Error message

startFrame[%,d] > endFrame[%,d]

What it means

The constructor also requires startFrame <= endFrame; an inverted range selects no frames validly and is treated as a caller bug, throwing IAE. This prevents silently reading nothing or misadvancing frame cursors.

Source

Thrown at processing/src/main/java/org/apache/druid/frame/channel/ReadableFileFrameChannel.java:63

  public ReadableFileFrameChannel(
      final FrameFile frameFile,
      final int startFrame,
      final int endFrame,
      final WireTransferable.ConcreteDeserializer deserializer
  )
  {
    this.frameFile = frameFile;
    this.deserializer = deserializer;
    this.currentFrame = startFrame;
    this.endFrame = endFrame;

    if (startFrame < 0) {
      throw new IAE("startFrame[%,d] < 0", startFrame);
    }

    if (startFrame > endFrame) {
      throw new IAE("startFrame[%,d] > endFrame[%,d]", startFrame, endFrame);
    }

    if (endFrame > frameFile.numFrames()) {
      throw new IAE("endFrame[%,d] > numFrames[%,d]", endFrame, frameFile.numFrames());
    }
  }

  public ReadableFileFrameChannel(
      final FrameFile frameFile,
      final WireTransferable.ConcreteDeserializer deserializer
  )
  {
    this(frameFile, 0, frameFile.numFrames(), deserializer);
  }

  @Override
  public boolean isFinished()
  {

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Swap or recompute the range so startFrame <= endFrame.
  2. Validate partition ranges before constructing the channel.
  3. Check the partition-assignment logic for argument ordering bugs.

Example fix

// before
new ReadableFileFrameChannel(frameFile, deserializer, endFrame, startFrame); // swapped
// after
new ReadableFileFrameChannel(frameFile, deserializer, startFrame, endFrame);
Defensive patterns

Strategy: validation

Validate before calling

if (startFrame > endFrame) { throw new IllegalArgumentException("startFrame must be <= endFrame"); }

Type guard

boolean validRange(int startFrame, int endFrame) { return startFrame >= 0 && startFrame <= endFrame; }

Try / catch

try { new ReadableFileFrameChannel(f, d, startFrame, endFrame); } catch (IAE e) { if (e.getMessage().contains("> endFrame")) { /* fix range ordering and retry */ } else { throw e; } }

Prevention

When it happens

Trigger: Constructing ReadableFileFrameChannel with startFrame > endFrame, e.g. swapped arguments or a partition range computed from wrong ordering.

Common situations: Swapping parameter order at call sites; partition-assignment code emitting reversed ranges; off-by-one logic where start is computed after end.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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