apache/beam · error · IllegalArgumentException
offset is negative:
Error message
offset is negative:
What it means
TextSource.SubstringByteArrayOutputStream.toString(int offset, int length, Charset) validates its arguments before creating a substring from the internal buffer. If offset is negative it throws IllegalArgumentException immediately. This guard exists because a negative offset would otherwise be an ArrayIndexOutOfBoundsException or produce silent wrong output in the underlying ByteArrayOutputStream.toString.
Source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/io/TextSource.java:472
str.reset();
return true;
}
}
/**
* This class is created to avoid multiple bytes-copy when making a substring of the output.
* Without this class, it requires two bytes copies.
*
* <pre>{@code
* ByteArrayOutputStream out = ...;
* byte[] buffer = out.toByteArray(); // 1st-copy
* String s = new String(buffer, offset, length); // 2nd-copy
* }</pre>
*/
static class SubstringByteArrayOutputStream extends ByteArrayOutputStream {
public String toString(int offset, int length, Charset charset) {
if (offset < 0) {
throw new IllegalArgumentException("offset is negative: " + offset);
}
if (offset > count) {
throw new IllegalArgumentException(
"offset exceeds the buffer limit. offset: " + offset + ", limit: " + count);
}
if (length < 0) {
throw new IllegalArgumentException("length is negative: " + length);
}
if (offset + length > count) {
throw new IllegalArgumentException(
"offset + length exceeds the buffer limit. offset: "
+ offset
+ ", length: "
+ length
+ ", limit: "
+ count);View on GitHub (pinned to 12126d8942)
Solutions
- Validate/normalize the offset before calling: Math.max(0, offset) or check `if (offset >= 0)` in caller code.
- Fix the computation producing the negative offset (e.g. re-derive start position from the record delimiter index).
- If offset is intentionally invalid, throw a descriptive error in caller code instead of reaching the buffer slicing API.
Example fix
// before String s = substringBuffer.toString(start - headerSize, recordLength, StandardCharsets.UTF_8); // after int off = Math.max(0, start - headerSize); String s = substringBuffer.toString(off, recordLength, StandardCharsets.UTF_8);
Defensive patterns
Strategy: validation
Validate before calling
checkArgument(offset >= 0, "offset must be non-negative, got %s", offset);
Try / catch
try {
String s = buffer.toString(offset, len, UTF_8);
} catch (IllegalArgumentException e) {
throw new IllegalStateException("bad record slice: " + e.getMessage(), e);
} Prevention
- Validate offsets derived from arithmetic (especially subtraction) before slicing.
- Clamp with Math.max(0, offset) when underflow is possible.
- Add unit tests for zero and boundary offsets.
When it happens
Trigger: Calling toString(offset, length, charset) on a SubstringByteArrayOutputStream with offset < 0, typically when a caller computed the offset from a subtraction (e.g. start - something) that underflowed or used an uninitialized value.
Common situations: Custom record boundary logic in TextSource subclasses computing substring offsets from header sizes; tests exercising invalid ranges; off-by-one bugs where an index variable was decremented below zero before slicing the buffer.
Related errors
- offset exceeds the buffer limit. offset: , limit:
- length is negative:
- offset + length exceeds the buffer limit. offset: , length:
- Failed closing channel to %s
- Error determining if %s allows dynamic splitting
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/15fdce3324e46466.
Report an issue: GitHub.