apache/hadoop · error · EOFException
position is negative in range {range}
Error message
position is negative in range {range} What it means
Thrown by VectoredReadUtils.validateRangeRequest when a FileRange submitted to a vectored read has a negative offset. Per the method's contract (and slightly unusually), a negative offset raises EOFException while a negative length raises IllegalArgumentException. Validation runs inside validateAndSortRanges/readVectored before any I/O, so this always indicates a caller bug constructing ranges, not a stream condition.
Source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/VectoredReadUtils.java:83
/**
* Validate a single range.
* @param range range to validate.
* @return the range.
* @param <T> range type
* @throws IllegalArgumentException the range length is negative or other invalid condition
* is met other than the those which raise EOFException or NullPointerException.
* @throws EOFException the range offset is negative
* @throws NullPointerException if the range is null.
*/
public static <T extends FileRange> T validateRangeRequest(T range)
throws EOFException {
requireNonNull(range, "range is null");
checkArgument(range.getLength() >= 0, "length is negative in %s", range);
if (range.getOffset() < 0) {
throw new EOFException("position is negative in range " + range);
}
return range;
}
/**
* Validate a list of vectored read ranges.
* @param ranges list of ranges.
* @throws EOFException any EOF exception.
*/
public static void validateVectoredReadRanges(List<? extends FileRange> ranges)
throws EOFException {
validateAndSortRanges(ranges, Optional.empty());
}
/**
* This is the default implementation which iterates through the ranges
* to read each synchronously, but the intent is that subclasses
* can make more efficient readers.View on GitHub (pinned to 2add963021)
Solutions
- Fix the range construction: clamp or reject offsets < 0 before creating FileRange objects
- Check intermediate arithmetic for underflow (use Math.max(0, pos - delta)) and for int-to-long sign extension
- Validate the whole list up front with VectoredReadUtils.validateVectoredReadRanges so failures surface at range-build time with full context
Example fix
// before
long offset = index * chunkSize - delta; // may go negative
FileRange r = FileRange.createFileRange(offset, len);
// after
long offset = Math.max(0L, index * chunkSize - delta);
if (offset < 0L || len < 0) {
throw new IllegalArgumentException("Invalid range: offset=" + offset + " len=" + len);
}
FileRange r = FileRange.createFileRange(offset, len); Defensive patterns
Strategy: validation
Validate before calling
static boolean isValidRange(long offset, int len) {
return offset >= 0 && len >= 0;
}
List<FileRange> safe = new ArrayList<>();
for (FileRange r : ranges) {
if (isValidRange(r.getOffset(), r.getLength())) {
safe.add(r);
} else {
throw new IllegalArgumentException("Bad range: offset=" + r.getOffset()
+ " len=" + r.getLength());
}
}
fs.readVectored(f, safe, allocate); Try / catch
try {
VectoredReadUtils.validateVectoredReadRanges(ranges);
} catch (EOFException e) {
// "position is negative in range ..." -> range-construction bug upstream
throw new IllegalArgumentException("Ranges built with negative offset", e);
} catch (IllegalArgumentException e) {
// negative length or overlapping ranges
throw e;
} Prevention
- Validate offsets/lengths at FileRange construction time, not at read time
- Unit-test chunk arithmetic at boundaries (offset 0, first/last chunk) with property-based tests
- Remember the contract: negative offset -> EOFException, negative length -> IllegalArgumentException
When it happens
Trigger: fs.readVectored(stream, ranges) / validateVectoredReadRanges where a FileRange was built with offset < 0: chunk-offset arithmetic underflow (index * chunkSize - delta), signed overflow of a long computed from an int, or parsing a negative offset from user input.
Common situations: Custom columnar/parquet readers computing stripe offsets; unit tests generating ranges at boundaries; code ported from an API where negative offsets wrapped around.
Related errors
- Path must be absolute: " + path
- Rename dir to self is forbidden
- Wrong scheme: %s, in path: %s, expected scheme: %s
- Wrong bucket: %s, in path: %s, expected bucket: %s
- GCS path supports only '%s' scheme, instead got '%s' from '%
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/1bbfb9ea9bb8334b.
Report an issue: GitHub.