apache/druid · error · IllegalArgumentException
startFrame[%,d] < 0
Error message
startFrame[%,d] < 0
What it means
ReadableFileFrameChannel reads a range of frames from a FrameFile. The constructor validates that startFrame is non-negative; a negative start frame is meaningless and throws IAE immediately. This is straightforward caller input validation.
Source
Thrown at processing/src/main/java/org/apache/druid/frame/channel/ReadableFileFrameChannel.java:59
private final FrameFile frameFile;
private final WireTransferable.ConcreteDeserializer deserializer;
private final int endFrame;
private int currentFrame;
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);
}View on GitHub (pinned to 9b90983fd2)
Solutions
- Clamp startFrame to 0 before constructing the channel.
- Fix the computation producing the negative index (check partition arithmetic).
- Validate frame-range inputs at the configuration layer before creating the channel.
Example fix
// before new ReadableFileFrameChannel(frameFile, deserializer, startFrame, endFrame); // startFrame = -1 // after startFrame = Math.max(0, startFrame); new ReadableFileFrameChannel(frameFile, deserializer, startFrame, endFrame);
Defensive patterns
Strategy: validation
Validate before calling
if (startFrame < 0) { throw new IllegalArgumentException("startFrame must be >= 0: " + startFrame); } Type guard
boolean validStart(int startFrame) { return startFrame >= 0; } Try / catch
try { new ReadableFileFrameChannel(f, d, startFrame, endFrame); } catch (IAE e) { if (e.getMessage().contains("startFrame") && e.getMessage().contains("< 0")) { startFrame = 0; /* retry */ } else { throw e; } } Prevention
- Clamp computed start indices to 0.
- Validate partition ranges at config/assignment time.
- Avoid sentinel -1 values for frame indices.
When it happens
Trigger: Constructing ReadableFileFrameChannel with startFrame < 0, e.g. passing -1 as a sentinel or computing a start index from an empty/underflowed counter.
Common situations: Off-by-one arithmetic producing -1 for the first partition; passing default/uninitialized partition metadata; int underflow when deriving frame ranges.
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
- startFrame[%,d] > endFrame[%,d]
- Emit called unexpectedly before service start
- Got an exception while parsing file [%s]
- Unable to copy key [%s] to file [%s]
- Frame of size [%,d] not yet ready to read
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/506726b4bb23e09b.
Report an issue: GitHub.