TeamNewPipe/NewPipe · error · IOException
invalid file length. expected = %s found = %s
Error message
invalid file length. expected = %s found = %s
What it means
Thrown by ChunkFileInputStream when the underlying source stream is shorter than the requested chunk end offset: source.length() < end. The chunk declares it will read up to 'end' but the file is not that long, so reading would hit EOF prematurely. The constructor closes the source (in a finally block) and throws an IOException with the expected vs found lengths.
Source
Thrown at app/src/main/java/us/shandian/giga/io/ChunkFileInputStream.java:32
private long progressReport;
private final ProgressReport onProgress;
public ChunkFileInputStream(SharpStream target, long start, long end, ProgressReport callback) throws IOException {
source = target;
offset = start;
length = end - start;
position = 0;
onProgress = callback;
progressReport = REPORT_INTERVAL;
if (length < 1) {
source.close();
throw new IOException("The chunk is empty or invalid");
}
if (source.length() < end) {
try {
throw new IOException(String.format("invalid file length. expected = %s found = %s", end, source.length()));
} finally {
source.close();
}
}
source.seek(offset);
}
/**
* Get absolute position on file
*
* @return the position
*/
public long getFilePointer() {
return offset + position;
}
@OverrideView on GitHub (pinned to 9e8be09156)
Solutions
- Verify source.length() >= end before constructing the stream (the same check the constructor does, done earlier with a clearer error).
- Re-download the file from scratch if the on-disk size does not match the expected total size.
- After an interrupted download, re-stat the file and recompute chunk bounds against the actual length.
- Validate the server's Content-Length against the range request before allocating chunks.
Example fix
// before
new ChunkFileInputStream(stream, start, end, callback);
// after — guard against truncation
if (stream.length() < end) {
throw new IOException("File truncated: need " + end + " bytes, have " + stream.length());
}
new ChunkFileInputStream(stream, start, end, callback); Defensive patterns
Strategy: validation
Validate before calling
// Verify source length covers the chunk end before constructing:
if (source.length() < end) {
throw new IOException("Source truncated: need offset " + end + ", have " + source.length());
} Try / catch
try {
ChunkFileInputStream in = new ChunkFileInputStream(stream, start, end, callback);
} catch (IOException e) {
if (e.getMessage() != null && e.getMessage().startsWith("invalid file length")) {
// file truncated — re-download from scratch
triggerFullRedownload();
} else throw e;
} Prevention
- Re-stat the file and recompute chunk bounds against actual on-disk size when resuming.
- Verify server Content-Length matches before allocating chunk offsets.
- Treat a truncated source as requiring a full re-download, not a partial resume.
When it happens
Trigger: new ChunkFileInputStream(target, start, end, callback) where source.length() < end. Caused by the file being truncated (download incomplete), a Content-Length/Content-Range mismatch where the server lied about the size, or stale size metadata used to compute chunk bounds.
Common situations: Resuming an interrupted download where the partial file is shorter than recorded; the server returned a different (smaller) file than expected; the file was deleted or truncated between size-discovery and chunk-read; mismatch between declared file size and actual bytes on disk.
Related errors
- The chunk is empty or invalid
- Cannot create a temporal file
- Truncated stream, missing {} bytes
- EOF reached in box: type=%s offset=%s size=%s
- EOF reached while reading a sample
AI-assisted analysis of TeamNewPipe/NewPipe@9e8be09156 (2026-08-14).
Data as JSON: /api/errors/4f8cdb5705f048b5.
Report an issue: GitHub.