bzip2 has no official specification: the format is what Julian Seward’s bzip2
program and its library, libbzip2, read and write. Joe Tsai’s
format
description sets it out from the bzip2 sources. This page follows it, with
bzip2’s own bzip2.c and manual page from
sourceware.org, all read
2026-11-12; the examples were checked with Python’s bz2 module. A .bz2 file is one or
more streams, and each stream is a 4-byte header, any number of
blocks and an end of stream.
Bits
After the header a stream is a sequence of bits with no byte alignment: a block can
start at any bit, and only the end of the stream is padded to a whole byte. Bits are
taken from the most significant bit of each byte down (the opposite of Deflate), and
a field of several bits is read most significant bit first, so the 32-bit CRCs read
as big-endian numbers. For example, the bytes EE 5C are the bits
1110 1110 0101 1100, and a 4-bit field followed by a 6-bit field there
holds 14 and 57.
Stream header
| Offset | Size | Field | Meaning |
|---|---|---|---|
0 | 2 | Magic | 42 5A, the letters BZ. |
2 | 1 | Version | 68, the letter h, for Huffman coding. The older, deprecated BZip1 format used 0 here. |
3 | 1 | Level | 31 to 39, the digits 1 to 9: blocks hold up to 100,000 × that many bytes before sorting. Any other value is not a bzip2 stream. |
The level is the -1 to -9 option of bzip2 (-9,
900,000-byte blocks, is the default). The bzip2 manual gives the memory each needs:
about 400 KB + 8 × the block size to compress, and 100 KB + 4 × the block size to
decompress, or 100 KB + 2.5 × the block size in its slower -s mode.
| Level | Block size | Level | Block size |
|---|---|---|---|
| 1 | 100,000 bytes | 6 | 600,000 bytes |
| 2 | 200,000 bytes | 7 | 700,000 bytes |
| 3 | 300,000 bytes | 8 | 800,000 bytes |
| 4 | 400,000 bytes | 9 | 900,000 bytes |
| 5 | 500,000 bytes |
End of stream
The last block is followed, at the very next bit, by:
| Bits | Field | Meaning |
|---|---|---|
| 48 | End-of-stream magic | 17 72 45 38 50 90: the first digits of √π in binary-coded decimal, as the block magic 31 41 59 26 53 59 is π. A decoder reads 48 bits where a block or the end may start and tells them apart by these values; anything else is an error. |
| 32 | Stream CRC | The block CRCs combined (see CRCs). 0 for a stream with no blocks. |
| 0 to 7 | Padding | Bits up to the next byte boundary. They need not be zeros, but encoders are strongly encouraged to write zeros. |
CRCs
Each block carries the CRC of the bytes it decompresses to. It is a CRC-32 with the
polynomial 04C11DB7, worked most significant bit first (not reflected),
starting from FFFFFFFF and inverted at the end: the CRC sometimes called
CRC-32/BZIP2. The bytes 123456789 give FC891918. It uses the
same polynomial as gzip’s CRC-32, but bit-reversed in every way, so the two do not
give the same values.
The stream CRC starts at 0. For each block in turn it is rotated left by one bit and then XORed with the block’s CRC:
combined = ((combined << 1) | (combined >> 31)) ^ blockCRC
A stream of one block therefore has the block’s CRC as its stream CRC. bzip2 checks each block’s CRC when it has decoded the block, and the stream CRC at the end, against the CRCs it computed. A wrong CRC is a data error.
Several streams, and what follows
Streams may follow one another: the next stream’s BZh header starts at
the byte after the last one’s padding. bzip2 decompresses each in turn and joins the
output, so cat a.bz2 b.bz2 makes a file that decompresses to both (the
manual page describes this). Each stream has its own header, so a stream may use a
different level from the one before.
If the bytes after a stream are not another stream header, bzip2 ignores them
and warns of trailing garbage; zeros left by a tape or a disk image are treated the
same way. Bytes that start with a valid header, BZh and a digit from
1 to 9, must be a whole stream, or bzip2 reports the file as
damaged.
When decompressing, bzip2 names the output after the input: .bz2 and
.bz are dropped, .tbz2 and .tbz become
.tar, and any other name gets .out added.
Examples
An empty input compresses to 14 bytes, a header and an end of stream with no blocks between them:
42 5A 68 39 BZh9: level 9
17 72 45 38 50 90 end-of-stream magic
00 00 00 00 stream CRC 0 (no padding: the end is already on a byte)
The six bytes banana compress, at level 9, to 39 bytes:
42 5A 68 39 31 41 59 26 53 59 EF B6 EC 01 00 00
01 81 00 30 01 20 00 30 CC 0C 7A 88 5E 2E E4 8A
70 A1 21 DF 6D D8 02
The block starts at bit 32 (byte 4) with its magic, and its CRC is
EFB6EC01; the blocks
page takes it apart. The block ends at bit 231, inside byte 28, where the end-of-stream
magic 17 72 45 38 50 90 starts at the last bit of that byte, and so is
not visible byte by byte. The stream CRC EFB6EC01, the same as the one
block’s, follows, and one zero bit of padding ends the file.
Damaged files
Because every block starts with its 48-bit magic and has its own CRC, the blocks of a damaged file can be found by searching for the magic at every bit position, and each checked on its own. bzip2recover, which comes with bzip2, does this and writes every block it finds into a file of its own. The explorer does the same for the rest of a file after damage, and for files too large to decode while they are being read.