apache/iceberg · error · EOFException

Not enough bytes to skip

Error message

Not enough bytes to skip: <skipped> < <length>

What it means

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.

Solutions

  1. Verify the number of bytes to skip against remaining bytes (input stream length minus current position) before calling skipFully.
  2. Re-check the parsing offsets/lengths upstream — a skipped length larger than remaining data usually indicates a misread header or truncated buffer.
  3. Use skip() and check the return value if partial skips are acceptable, or catch java.io.EOFException.

Example fix

// before
in.skipFully(headerLen); // may throw EOFException
// after
long remaining = totalLen - pos;
if (headerLen <= remaining) {
  in.skipFully(headerLen);
}
Defensive patterns

Strategy: validation

Validate before calling

if (length > in.available()) { throw new IOException("skip exceeds remaining bytes"); } // guard before skipFully

Try / catch

try {
  in.skipFully(length);
} catch (EOFException e) {
  // buffer truncated: surface a corruption/truncation error
}

Prevention

When it happens

Trigger: Calling skipFully(n) when fewer than n bytes remain between the current position and the end of the underlying ByteBuffer(s).

Common situations: 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.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/2dfc499758fd284f. Report an issue: GitHub.

Appendix: source

Thrown at core/src/main/java/org/apache/iceberg/io/ByteBufferInputStream.java:48

    if (buffers.length == 1) {
      return new SingleBufferInputStream(buffers[0]);
    } else {
      return new MultiBufferInputStream(Arrays.asList(buffers));
    }
  }

  public static ByteBufferInputStream wrap(List<ByteBuffer> buffers) {
    if (buffers.size() == 1) {
      return new SingleBufferInputStream(buffers.get(0));
    } else {
      return new MultiBufferInputStream(buffers);
    }
  }

  public void skipFully(long length) throws IOException {
    long skipped = skip(length);
    if (skipped < length) {
      throw new EOFException("Not enough bytes to skip: " + skipped + " < " + length);
    }
  }

  public abstract int read(ByteBuffer out);

  public abstract ByteBuffer slice(int length) throws EOFException;

  public abstract List<ByteBuffer> sliceBuffers(long length) throws EOFException;

  public ByteBufferInputStream sliceStream(long length) throws EOFException {
    return ByteBufferInputStream.wrap(sliceBuffers(length));
  }

  public abstract List<ByteBuffer> remainingBuffers();

  public ByteBufferInputStream remainingStream() {
    return ByteBufferInputStream.wrap(remainingBuffers());
  }

View on GitHub (pinned to 86d9c8fc54)