{"record":{"id":"acaac2805224ca9e","repo":"apache/iceberg","slug":"cannot-read-length-bytes-at-position-pos-exce","errorCode":null,"errorMessage":"Cannot read <length> bytes at position <pos>: exceeds stream length <contents.length>","messagePattern":"Cannot read <length> bytes at position <pos>: exceeds stream length <contents\\.length>","errorType":"exception","errorClass":"EOFException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/io/EagerInputStream.java","lineNumber":78,"sourceCode":"    return delegate.read(b, off, len);\n  }\n\n  @Override\n  public long skip(long n) throws IOException {\n    return delegate.skip(n);\n  }\n\n  @Override\n  public int available() throws IOException {\n    return delegate.available();\n  }\n\n  @Override\n  public void readFully(long pos, byte[] buffer, int offset, int length) throws IOException {\n    Preconditions.checkPositionIndexes(offset, offset + length, buffer.length);\n    Preconditions.checkArgument(pos >= 0, \"position is negative: %s\", pos);\n    if (pos > contents.length || length > contents.length - pos) {\n      throw new EOFException(\n          \"Cannot read \"\n              + length\n              + \" bytes at position \"\n              + pos\n              + \": exceeds stream length \"\n              + contents.length);\n    }\n    System.arraycopy(contents, (int) pos, buffer, offset, length);\n  }\n\n  @Override\n  public int readTail(byte[] buffer, int offset, int length) throws IOException {\n    Preconditions.checkPositionIndexes(offset, offset + length, buffer.length);\n    int bytesToCopy = Math.min(length, contents.length);\n    System.arraycopy(contents, contents.length - bytesToCopy, buffer, offset, bytesToCopy);\n    return bytesToCopy;\n  }\n","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/io/EagerInputStream.java#L60-L96","documentation":"EagerInputStream.readFully throws EOFException when the requested [pos, pos+length) window lies beyond the in-memory contents array. It is a bounds check that prevents partial reads from the fixed-size byte buffer backing the eager stream.","triggerScenarios":"Calling readFully(pos, buffer, offset, length) where pos > contents.length or pos + length > contents.length on a stream from EagerInputFile.newStream().","commonSituations":"Footer parsers requesting ranges beyond a truncated/stale buffer; using offsets from metadata that referenced a larger file; off-by-one or wrong length computations in read loops.","solutions":["Clamp or validate pos and length against the file length before reading.","Refresh the eager contents — the buffer may be stale or truncated (see the incorrect-length error).","Fix the offset/length source (footer metadata) if it points outside the file.","Use the stream's length() to size reads dynamically."],"exampleFix":"// before\nstream.readFully(pos, buf, 0, buf.length);\n// after\nlong len = stream.getLength();\nlong readable = Math.min(buf.length, len - pos);\nif (readable <= 0) throw new IllegalArgumentException(\"pos \" + pos + \" beyond end of stream\");\nstream.readFully(pos, buf, 0, (int) readable);","handlingStrategy":"validation","validationCode":"long fileLen = stream.getLength();\nif (pos < 0 || pos > fileLen || length > fileLen - pos) {\n  throw new IllegalArgumentException(\"Read window out of bounds\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  stream.readFully(pos, buf, offset, length);\n} catch (EOFException e) {\n  LOG.error(\"Read [{}..{}] beyond length {}\", pos, pos + length, contentsLength);\n  throw e;\n}","preventionTips":["Compute lengths from the stream's own getLength(), not assumptions","Validate footer-derived ranges before reading","Refresh eager contents if the buffer may be stale/truncated","Prefer the positional readFully over seek+read loops for bulk reads"],"tags":["read","out-of-range","memory-stream"],"backgroundTag":"value-out-of-range","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}