MuntashirAkon/AppManager · error · IOException
Unexpected end of stream
Error message
Unexpected end of stream
What it means
bsR() reads n bits via the underlying BitInputStream and throws IOException("Unexpected end of stream") when readBits returns a negative EOF marker. The stream ended while the decoder still expected structural data (block header, selectors, Huffman tables, or CRC).
Source
Thrown at app/src/main/java/org/apache/commons/compress/compressors/bzip2/BZip2CompressorInputStream.java:372
try {
inShadow.close();
} finally {
this.data = null;
this.bin = null;
}
}
}
/**
* read bits from the input stream
* @param n the number of bits to read, must not exceed 32?
* @return the requested bits combined into an int
* @throws IOException
*/
private static int bsR(final BitInputStream bin, final int n) throws IOException {
final long thech = bin.readBits(n);
if (thech < 0) {
throw new IOException("Unexpected end of stream");
}
return (int) thech;
}
private static boolean bsGetBit(final BitInputStream bin) throws IOException {
return bsR(bin, 1) != 0;
}
private static char bsGetUByte(final BitInputStream bin) throws IOException {
return (char) bsR(bin, 8);
}
private static int bsGetInt(final BitInputStream bin) throws IOException {
return bsR(bin, 32);
}
private static void checkBounds(final int checkVal, final int limitExclusive, final String name)
throws IOException {View on GitHub (pinned to 0152f468fc)
Solutions
- Ensure the compressed input is complete: wait for the producer to finish and close, or re-download fully.
- Verify the file with `bzip2 -t` (reports 'unexpected end of file' for truncated archives).
- Always close() the compressor OutputStream on the producer side so the end-of-stream trailer is written.
- Catch IOException and handle truncation explicitly if partial data is acceptable, but do not retry reading the same truncated source.
Example fix
// before
// producer side: forgot to close, trailer missing
compressorOutputStream.finish(); // incomplete: no close()
// after
try (BZip2CompressorOutputStream out = new BZip2CompressorOutputStream(fileOut)) {
out.write(data);
} // close() writes the stream trailer Defensive patterns
Strategy: try-catch
Validate before calling
// check completeness before decompress
long expected = manifest.get(name);
if (file.length() < expected) throw new IOException("truncated download: " + file); Try / catch
try {
readAll(in);
} catch (IOException e) {
if ("Unexpected end of stream".equals(e.getMessage())) {
// source truncated: re-download or wait for producer to finish
throw new TruncatedInputException(e);
}
throw e;
} Prevention
- Only read .bz2 files after the producer has closed them.
- Close compressor OutputStreams (try-with-resources) so trailers are written.
- Retry truncated downloads from scratch; do not resume bitstream reads.
When it happens
Trigger: A truncated .bz2 file (download cut off, write not flushed/closed); the underlying InputStream hit EOF mid-block or before the stream trailer; feeding a stream that is still being written concurrently.
Common situations: Partially downloaded files; producer not closing the OutputStream so the compressor never flushed the trailer; reading over an unstable socket connection; reading a file currently being written by another process.
Related errors
- Detect premature EOF
- Failed to sign
- Could not cache the APK file
- Could not get backup files.
- Could not retrieve metadata from backup.
AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12).
Data as JSON: /api/errors/9147b036a986bf6b.
Report an issue: GitHub.