MuntashirAkon/AppManager · error · IOException

Bad block header

Error message

Bad block header

What it means

initBlock() reads the 6-byte block magic (0x314159265359, 'BZh'-block pi digits) and, on mismatch, sets state to EOF and throws IOException("Bad block header"). This means the bit stream reached data that is neither a valid block nor the end-of-stream marker.

Solutions

  1. Verify the archive with `bzip2 -t` / re-download or re-compress the file.
  2. Do not seek or partially consume the underlying InputStream before wrapping it; decompress from byte 0.
  3. If reading concatenated streams, ensure each part is a complete valid bzip2 stream.
  4. Catch IOException and treat the data as unrecoverable rather than attempting partial parse.

Example fix

// before
FileInputStream fis = new FileInputStream(f);
fis.skip(100); // desyncs the bit reader
BZip2CompressorInputStream in = new BZip2CompressorInputStream(fis);
// after
BZip2CompressorInputStream in = new BZip2CompressorInputStream(new FileInputStream(f)); // from start
Defensive patterns

Strategy: try-catch

Try / catch

try {
    readAll(in);
} catch (IOException e) {
    if ("Bad block header".equals(e.getMessage())) {
        throw new CorruptArchiveException("bzip2 data corrupted or truncated", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Corrupt or truncated .bz2 data mid-stream; seeking/positioning the underlying InputStream to a non-block boundary; concatenated streams with invalid separators when decompressConcatenated is true.

Common situations: Incomplete downloads read as valid headers but corrupt blocks; passing a partially-flushed compressed stream; bit-level corruption in transit; parsing a stream already consumed past the end marker.

Related errors


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

Appendix: source

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

            }

            // End of stream was reached. Check the combined CRC and
            // advance to the next .bz2 stream if decoding concatenated
            // streams.
            if (complete()) {
                return;
            }
        }

        if (magic0 != 0x31 || // '1'
                magic1 != 0x41 || // ')'
                magic2 != 0x59 || // 'Y'
                magic3 != 0x26 || // '&'
                magic4 != 0x53 || // 'S'
                magic5 != 0x59 // 'Y'
        ) {
            this.currentState = EOF;
            throw new IOException("Bad block header");
        }
        this.storedBlockCRC = bsGetInt(bin);
        this.blockRandomised = bsR(bin, 1) == 1;

        /*
         * Allocate data here instead in constructor, so we do not allocate
         * it if the input file is empty.
         */
        if (this.data == null) {
            this.data = new Data(this.blockSize100k);
        }

        // currBlockNo++;
        getAndMoveToFrontDecode();

        this.crc.initializeCRC();
        this.currentState = START_BLOCK_STATE;
    }

View on GitHub (pinned to 0152f468fc)