apache/hadoop · error · EOFException
End of file reached before reading fully.
Error message
End of file reached before reading fully.
What it means
After the initial length check, ByteRangeInputStream.readFully reads in a loop until all requested bytes are transferred. If the underlying HTTP stream returns -1 before nread reaches length, it throws the shared FSExceptionMessages.EOF_IN_READ_FULLY EOFException. This means the server ended the response body earlier than the number of bytes the caller requested.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/web/ByteRangeInputStream.java:257
@Override
public void readFully(long position, byte[] buffer, int offset, int length)
throws IOException {
validatePositionedReadArgs(position, buffer, offset, length);
if (length == 0) {
return;
}
final InputStreamAndFileLength fin = openInputStream(position);
try {
if (fin.length != null && length + position > fin.length) {
throw new EOFException("The length to read " + length
+ " exceeds the file length " + fin.length);
}
int nread = 0;
while (nread < length) {
int nbytes = fin.in.read(buffer, offset + nread, length - nread);
if (nbytes < 0) {
throw new EOFException(FSExceptionMessages.EOF_IN_READ_FULLY);
}
nread += nbytes;
}
} finally {
fin.in.close();
}
}
/**
* Return the current offset from the start of the file
*/
@Override
public long getPos() throws IOException {
return currentPos;
}
/**
* Seeks a different copy of the data. Returns true ifView on GitHub (pinned to 2add963021)
Solutions
- Re-run getFileStatus(path), compare the new length with position + length, and either clamp the read or fail with a clear application error.
- Retry the read once on a fresh connection or another NameNode/DataNode if the length still covers the range and the failure looks transient.
- Inspect proxy or DataNode logs for truncated responses or reset connections when the reported file length is stable.
- Read only committed files, or coordinate truncation/append with readers, when another process may modify the file concurrently.
Example fix
// before
in.readFully(pos, buffer, 0, length);
// after
try {
in.readFully(pos, buffer, 0, length);
} catch (EOFException e) {
long currentLen = fs.getFileStatus(path).getLen();
if (pos + length > currentLen) {
throw new EOFException("File changed: need " + (pos + length)
+ " bytes, current length is " + currentLen, e);
}
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
FileStatus status = fs.getFileStatus(path);
if (position + length > status.getLen()) {
length = (int) Math.max(0, status.getLen() - position);
}
if (length > 0) {
in.readFully(position, buffer, offset, length);
} Try / catch
try {
in.readFully(position, buffer, offset, length);
} catch (EOFException e) {
FileStatus latest = fs.getFileStatus(path);
if (position + length <= latest.getLen()) {
// Length still covers the range: likely a truncated HTTP response or transient DN failure.
LOG.warn("Premature EOF for {}; retrying", path, e);
return readWithRetry(fs, path, position, buffer, offset, length);
}
throw e;
} Prevention
- Do not modify files while readers hold positioned ranges unless readers revalidate length after EOF.
- Monitor DataNode and proxy connection-reset metrics when these errors recur on stable files.
- Keep a single fresh FileStatus close in time to the read and never cache it across long jobs with mutable files.
When it happens
Trigger: readFully(position, buffer, offset, length) passes the initial range check, but the response body returns EOF after fewer than length bytes. Common concrete causes are concurrent truncation of the file, a stale server-reported length, an intermediate proxy truncating the range response, or a DataNode stream that fails during transfer.
Common situations: A file is deleted or truncated while a reader is active; a writer exposes an incomplete file before it is committed; an HTTP proxy or load balancer imposes a response-size limit; a DataNode becomes unhealthy during a large positioned read.
Related errors
- The length to read ${length} exceeds the file length ${fin.l
- Invalid value in server response: name=[${name}]
- Missing both 'ipAddr' and 'name' in server response.
- Invalid or missing 'xferPort' in server response.
- Unknown algorithm: ${algorithm}
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/817fc6a2838ef595.
Report an issue: GitHub.