apache/incubator-seata · error · RuntimeException
gzip decompress error
Error message
gzip decompress error
What it means
Wrapped IOException thrown by GzipUtil.decompress as RuntimeException("gzip decompress error", e). It fires when GZIPInputStream cannot read the payload: the data is not in gzip format (bad magic bytes), the stream is truncated/corrupted, or the CRC/checksum fails on finish. The original IOException is attached as the cause for diagnosis.
Source
Thrown at compressor/seata-compressor-gzip/src/main/java/org/apache/seata/compressor/gzip/GzipUtil.java:60
throw new RuntimeException("gzip compress error", e);
}
}
public static byte[] decompress(byte[] bytes) {
if (bytes == null) {
throw new NullPointerException("bytes is null");
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
try (GZIPInputStream gunzip = new GZIPInputStream(new ByteArrayInputStream(bytes))) {
byte[] buffer = new byte[BUFFER_SIZE];
int n;
while ((n = gunzip.read(buffer)) > -1) {
out.write(buffer, 0, n);
}
return out.toByteArray();
} catch (IOException e) {
throw new RuntimeException("gzip decompress error", e);
}
}
}
View on GitHub (pinned to e01f97c6db)
Solutions
- Inspect the cause in the stack trace — 'Not in GZIP format' means wrong data, 'Unexpected end of ZLIB input stream' means truncation.
- Verify the compressor id/type configured on both ends of the RPC matches (registry and compressor config).
- If data comes from storage, re-read or regenerate it (e.g. clear the poisoned undo_log rows) rather than retrying decompression.
- Sanity-check the first two bytes are 0x1f 0x8b before calling decompress.
Example fix
// before
byte[] out = GzipUtil.decompress(bytes);
// after
if (bytes.length < 2 || (bytes[0] & 0xff) != 0x1f || (bytes[1] & 0xff) != 0x8b) {
throw new IllegalArgumentException("payload is not gzip (bad magic bytes)");
}
byte[] out = GzipUtil.decompress(bytes); Defensive patterns
Strategy: try-catch
Validate before calling
boolean isGzip(byte[] b) {
return b != null && b.length >= 2 && (b[0] & 0xff) == 0x1f && (b[1] & 0xff) == 0x8b;
} Try / catch
try {
byte[] out = GzipUtil.decompress(bytes);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().contains("gzip decompress error")) {
// treat as corrupt/foreign payload: log cause, reject message, do not retry
} else { throw e; }
} Prevention
- Keep compressor type identical on client and server
- Check gzip magic bytes (0x1f 0x8b) before decompressing data of uncertain origin
- Never store compressed bytes in text-typed DB columns or through charset-recoding layers
When it happens
Trigger: Passing bytes that were not gzip-compressed (raw, zip, or lz4 payloads); a truncated byte array (partial network read, wrong length prefix); corrupted rollback-info stored in a database table; calling decompress on an empty non-null array (new byte[0]) which makes the GZIPInputStream constructor throw ZipException 'Not in GZIP format'.
Common situations: Compressor type mismatch between seata client and server (client compresses with zstd, server decompresses with gzip); corrupted undo_log/branch session data after a DB character-set incident; a proxy or middleware mangling binary bodies; version upgrade changing the default compressor.
Related errors
- Zip decompress error
- Failed to decompress zstd data
- Zip compress error
- gzip compress error
- bytes is null
AI-assisted analysis of apache/incubator-seata@e01f97c6db (2026-08-14).
Data as JSON: /api/errors/3cd9f0e0db8eaf14.
Report an issue: GitHub.