apache/incubator-seata · error · RuntimeException
BZip2 decompress error
Error message
BZip2 decompress error
What it means
BZip2Util.decompress wraps IOException from CBZip2InputStream in RuntimeException('BZip2 decompress error'). commons-compress throws IOException for invalid stream headers, truncated data, or CRC mismatches, so this exception in Seata almost always means the bytes given are not a complete/valid bzip2 stream — commonly because they were compressed by a different algorithm or corrupted in transit.
Source
Thrown at compressor/seata-compressor-bzip2/src/main/java/org/apache/seata/compressor/bzip2/BZip2Util.java:62
throw new RuntimeException("BZip2 compress error", e);
}
}
public static byte[] decompress(byte[] bytes) {
if (bytes == null) {
throw new NullPointerException("bytes is null");
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
try (CBZip2InputStream bzip2 = new CBZip2InputStream(bis)) {
byte[] buffer = new byte[BUFFER_SIZE];
int n;
while ((n = bzip2.read(buffer)) > -1) {
out.write(buffer, 0, n);
}
return out.toByteArray();
} catch (IOException e) {
throw new RuntimeException("BZip2 decompress error", e);
}
}
}
View on GitHub (pinned to e01f97c6db)
Solutions
- Make compressor configuration symmetric on both peers (same seata transport/undo compressor id) and restart both sides after changing it.
- Check the first two bytes of the payload — a valid bzip2 stream starts with 'B' 'Z' (0x42 0x5A); if not, the data was not bzip2-compressed.
- Verify the payload length matches what the sender logged (detect truncation).
- Catch RuntimeException around decompress and surface the IOException cause for precise diagnosis.
Example fix
// before
byte[] raw = BZip2Util.decompress(body);
// after
if (body.length < 2 || body[0] != 'B' || body[1] != 'Z') {
throw new IOException("payload is not bzip2 (bad magic) — check compressor config on both peers");
}
try {
byte[] raw = BZip2Util.decompress(body);
} catch (RuntimeException e) {
throw new IOException("bzip2 decompress failed", e.getCause());
} Defensive patterns
Strategy: try-catch
Validate before calling
// bzip2 streams start with magic 'BZ'
public static boolean looksLikeBzip2(byte[] data) {
return data != null && data.length >= 2
&& data[0] == 'B' && data[1] == 'Z';
} Try / catch
try {
return BZip2Util.decompress(bytes);
} catch (RuntimeException e) {
Throwable cause = e.getCause(); // original IOException
throw new IOException("bzip2 decompress failed (corrupt or wrong-compressor payload)", cause);
} Prevention
- Change compressor configuration on all peers in the same rollout window.
- Verify binary integrity end to end (no text-charset conversion in between).
- Keep a magic-byte sanity check in front of decompression in custom integrations.
When it happens
Trigger: decompress(bytes) where bytes was produced by gzip/deflater/zstd (compressor id mismatch between endpoints), by bzip2 without the leading 'BZ' magic (some CLI bzip2 variants differ), truncated by a size-limited channel, or double-encoded; also raw data passed where compressed data was expected.
Common situations: Client configured compressor: gzip while server expects bzip2 (or vice versa) after a config change rolled out partially; messages routed through proxies that mangle binary payloads; undo logs written uncompressed then read with bzip2 enabled; version drift in commons-compress changing stream validation strictness.
Related errors
AI-assisted analysis of apache/incubator-seata@e01f97c6db (2026-08-14).
Data as JSON: /api/errors/b453bcc1839c7aaf.
Report an issue: GitHub.