MuntashirAkon/AppManager · error · IOException

BZip2 block size is invalid

Error message

BZip2 block size is invalid

What it means

After the 'BZh' magic, the fourth byte must be '1'..'9' specifying the 100k block size used at compression time. init() throws IOException("BZip2 block size is invalid") when this byte is out of range, so the stream header is malformed or not bzip2 at all.

Solutions

  1. Validate the input file integrity (checksum the download, re-transfer).
  2. Confirm the file is genuine bzip2 output with `file` or `bzip2 -t`.
  3. Catch IOException from the BZip2CompressorInputStream constructor and fall back to a detected format.

Example fix

// before
InputStream in = new BZip2CompressorInputStream(new FileInputStream(maybeBz2));
// after
try {
    InputStream in = new BZip2CompressorInputStream(new FileInputStream(maybeBz2));
} catch (IOException e) {
    throw new IOException("Corrupt or non-bzip2 input: " + e.getMessage(), e);
}
Defensive patterns

Strategy: validation

Validate before calling

PushbackInputStream pb = new PushbackInputStream(src, 4);
byte[] h = new byte[4];
if (pb.read(h) != 4 || h[0] != 'B' || h[1] != 'Z' || h[2] != 'h'
        || h[3] < '1' || h[3] > '9') {
    pb.unread(h);
    throw new IllegalArgumentException("malformed bzip2 header");
}
pb.unread(h);

Type guard

static boolean hasValidBlockSize(byte[] head) {
    return head.length >= 4 && head[3] >= '1' && head[3] <= '9';
}

Try / catch

try {
    InputStream in = new BZip2CompressorInputStream(pb);
} catch (IOException e) {
    if (String.valueOf(e.getMessage()).contains("block size is invalid")) {
        throw new IOException("corrupt bzip2 header", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: A stream whose 4th byte is not an ASCII digit 1-9 — truncated/corrupt headers, files starting with 'BZh' by coincidence, or corrupted first block.

Common situations: Partially downloaded .bz2 files; binary files that happen to start with 'BZh'; man-in-the-middle or transfer corruption; hand-crafted or fuzzed inputs.

Related errors


AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12). Data as JSON: /api/errors/a288db5b351be5bd. Report an issue: GitHub.

Appendix: source

Thrown at app/src/main/java/org/apache/commons/compress/compressors/bzip2/BZip2CompressorInputStream.java:247

            bin.clearBitCache();
        }

        final int magic0 = readNextByte(this.bin);
        if (magic0 == -1 && !isFirstStream) {
            return false;
        }
        final int magic1 = readNextByte(this.bin);
        final int magic2 = readNextByte(this.bin);

        if (magic0 != 'B' || magic1 != 'Z' || magic2 != 'h') {
            throw new IOException(isFirstStream
                    ? "Stream is not in the BZip2 format"
                    : "Garbage after a valid BZip2 stream");
        }

        final int blockSize = readNextByte(this.bin);
        if ((blockSize < '1') || (blockSize > '9')) {
            throw new IOException("BZip2 block size is invalid");
        }

        this.blockSize100k = blockSize - '0';

        this.computedCombinedCRC = 0;

        return true;
    }

    private void initBlock() throws IOException {
        final BitInputStream bin = this.bin;
        char magic0;
        char magic1;
        char magic2;
        char magic3;
        char magic4;
        char magic5;

View on GitHub (pinned to 0152f468fc)