{"record":{"id":"ee5d9487296c9c5f","repo":"MuntashirAkon/AppManager","slug":"bad-block-header","errorCode":null,"errorMessage":"Bad block header","messagePattern":"Bad block header","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/org/apache/commons/compress/compressors/bzip2/BZip2CompressorInputStream.java","lineNumber":297,"sourceCode":"            }\n\n            // End of stream was reached. Check the combined CRC and\n            // advance to the next .bz2 stream if decoding concatenated\n            // streams.\n            if (complete()) {\n                return;\n            }\n        }\n\n        if (magic0 != 0x31 || // '1'\n                magic1 != 0x41 || // ')'\n                magic2 != 0x59 || // 'Y'\n                magic3 != 0x26 || // '&'\n                magic4 != 0x53 || // 'S'\n                magic5 != 0x59 // 'Y'\n        ) {\n            this.currentState = EOF;\n            throw new IOException(\"Bad block header\");\n        }\n        this.storedBlockCRC = bsGetInt(bin);\n        this.blockRandomised = bsR(bin, 1) == 1;\n\n        /*\n         * Allocate data here instead in constructor, so we do not allocate\n         * it if the input file is empty.\n         */\n        if (this.data == null) {\n            this.data = new Data(this.blockSize100k);\n        }\n\n        // currBlockNo++;\n        getAndMoveToFrontDecode();\n\n        this.crc.initializeCRC();\n        this.currentState = START_BLOCK_STATE;\n    }","sourceCodeStart":279,"sourceCodeEnd":315,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/org/apache/commons/compress/compressors/bzip2/BZip2CompressorInputStream.java#L279-L315","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Verify the archive with `bzip2 -t` / re-download or re-compress the file.","Do not seek or partially consume the underlying InputStream before wrapping it; decompress from byte 0.","If reading concatenated streams, ensure each part is a complete valid bzip2 stream.","Catch IOException and treat the data as unrecoverable rather than attempting partial parse."],"exampleFix":"// before\nFileInputStream fis = new FileInputStream(f);\nfis.skip(100); // desyncs the bit reader\nBZip2CompressorInputStream in = new BZip2CompressorInputStream(fis);\n// after\nBZip2CompressorInputStream in = new BZip2CompressorInputStream(new FileInputStream(f)); // from start","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    readAll(in);\n} catch (IOException e) {\n    if (\"Bad block header\".equals(e.getMessage())) {\n        throw new CorruptArchiveException(\"bzip2 data corrupted or truncated\", e);\n    }\n    throw e;\n}","preventionTips":["Always decompress from position 0; never seek/skip in the underlying stream.","Let close()/EOF terminate reading instead of guessing stream length.","Verify archives with bzip2 -t before processing."],"tags":["io","corrupt-data","block-header"],"backgroundTag":"invalid-stream-format","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}