apache/iceberg · warning · IOException
Failed to read bytes: bytes in stream
Error message
Failed to read %d bytes: %d bytes in stream
What it means
During ContentCache.download, the cached read got fewer bytes than the file's declared length before reaching EOF. The cache is abandoned by throwing IOException so the caller falls back to a non-caching input stream; the message reports how many bytes were actually read.
Solutions
- Retry the read; the fallback non-caching path usually succeeds.
- Verify the object's current size matches the length in table metadata.
- Check for writers overwriting files in place; Iceberg files must be immutable.
- Investigate storage client/proxy truncation (timeouts, range request handling).
Example fix
// before ContentCache cache = new ContentCache(0, 64 * 1024 * 1024); // cache huge files, hit truncation // after ContentCache cache = new ContentCache(0, 8 * 1024 * 1024); // cache small files only
Defensive patterns
Strategy: retry
Validate before calling
long actualLength = delegate.getLength();
if (declaredLength != actualLength) { refreshMetadata(); } Try / catch
try {
return cachedInputFile.newStream();
} catch (IOException | UncheckedIOException e) {
return delegate.newStream(); // non-caching fallback is built in
} Prevention
- Treat Iceberg data files as immutable — never overwrite in place
- Use storage with atomic replace semantics
- Keep cached file sizes small to reduce truncation exposure
- Retry transiently on short reads; they are often storage blips
When it happens
Trigger: The input stream returned by the delegate ends prematurely: file truncated or rewritten to a smaller size after length was read, or the storage client returned a short/incomplete response body.
Common situations: Concurrent overwrite of an object in stores without atomic replace; corrupted/incomplete multipart upload; proxy or CDN truncating responses; stale length from stale metadata.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- Failed to open file
- An error occurred while aborting the stream
- An error occurred while closing the stream
- Bulk deletion failed
- Can't create file
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/c949f747d40935a5.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/apache/iceberg/io/ContentCache.java:257
}
private static FileContent download(InputFile input) {
try (SeekableInputStream stream = input.newStream()) {
long fileLength = input.getLength();
long totalBytesToRead = fileLength;
List<ByteBuffer> buffers = Lists.newArrayList();
while (totalBytesToRead > 0) {
// read the stream in chunks
int bytesToRead = (int) Math.min(BUFFER_CHUNK_SIZE, totalBytesToRead);
byte[] buf = new byte[bytesToRead];
int bytesRead = IOUtil.readRemaining(stream, buf, 0, bytesToRead);
totalBytesToRead -= bytesRead;
if (bytesRead < bytesToRead) {
// Read less than it should be, possibly hitting EOF. Abandon caching by throwing
// IOException and let the caller fallback to non-caching input file.
throw new IOException(
String.format(
Locale.ROOT,
"Failed to read %d bytes: %d bytes in stream",
fileLength,
fileLength - totalBytesToRead));
} else {
buffers.add(ByteBuffer.wrap(buf));
}
}
return new FileContent(fileLength, buffers);
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
}
}
View on GitHub (pinned to 86d9c8fc54)