{"record":{"id":"2dfc499758fd284f","repo":"apache/iceberg","slug":"not-enough-bytes-to-skip-skipped-length","errorCode":null,"errorMessage":"Not enough bytes to skip: <skipped> < <length>","messagePattern":"Not enough bytes to skip: <skipped> < <length>","errorType":"exception","errorClass":"EOFException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/io/ByteBufferInputStream.java","lineNumber":48,"sourceCode":"    if (buffers.length == 1) {\n      return new SingleBufferInputStream(buffers[0]);\n    } else {\n      return new MultiBufferInputStream(Arrays.asList(buffers));\n    }\n  }\n\n  public static ByteBufferInputStream wrap(List<ByteBuffer> buffers) {\n    if (buffers.size() == 1) {\n      return new SingleBufferInputStream(buffers.get(0));\n    } else {\n      return new MultiBufferInputStream(buffers);\n    }\n  }\n\n  public void skipFully(long length) throws IOException {\n    long skipped = skip(length);\n    if (skipped < length) {\n      throw new EOFException(\"Not enough bytes to skip: \" + skipped + \" < \" + length);\n    }\n  }\n\n  public abstract int read(ByteBuffer out);\n\n  public abstract ByteBuffer slice(int length) throws EOFException;\n\n  public abstract List<ByteBuffer> sliceBuffers(long length) throws EOFException;\n\n  public ByteBufferInputStream sliceStream(long length) throws EOFException {\n    return ByteBufferInputStream.wrap(sliceBuffers(length));\n  }\n\n  public abstract List<ByteBuffer> remainingBuffers();\n\n  public ByteBufferInputStream remainingStream() {\n    return ByteBufferInputStream.wrap(remainingBuffers());\n  }","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/io/ByteBufferInputStream.java#L30-L66","documentation":"ByteBufferInputStream.skipFully skips up to the requested number of bytes and throws EOFException when the buffer holds fewer bytes than requested. It enforces exact-length skipping over the in-memory buffer.","triggerScenarios":"Calling skipFully(n) when fewer than n bytes remain between the current position and the end of the underlying ByteBuffer(s).","commonSituations":"Reading binary formats whose computed field/skip lengths exceed the actual remaining buffer due to a misparsed header, truncated data, or an incorrect offset bookkeeping in custom deserialization code.","solutions":["Verify the number of bytes to skip against remaining bytes (input stream length minus current position) before calling skipFully.","Re-check the parsing offsets/lengths upstream — a skipped length larger than remaining data usually indicates a misread header or truncated buffer.","Use skip() and check the return value if partial skips are acceptable, or catch java.io.EOFException."],"exampleFix":"// before\nin.skipFully(headerLen); // may throw EOFException\n// after\nlong remaining = totalLen - pos;\nif (headerLen <= remaining) {\n  in.skipFully(headerLen);\n}","handlingStrategy":"validation","validationCode":"if (length > in.available()) { throw new IOException(\"skip exceeds remaining bytes\"); } // guard before skipFully","typeGuard":null,"tryCatchPattern":"try {\n  in.skipFully(length);\n} catch (EOFException e) {\n  // buffer truncated: surface a corruption/truncation error\n}","preventionTips":["Validate parsed lengths/offsets against the remaining buffer size before skipping.","Treat EOFException during skip as a sign of truncated or misparsed data.","Use skip() with return-value checks when partial progress is acceptable."],"tags":["io","buffer","eof","binary-parsing"],"backgroundTag":"index-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"}