apache/incubator-seata · error · RuntimeException
Deflater decompress error
Error message
Deflater decompress error
What it means
DeflaterUtil.decompress catches Exception — notably java.util.zip.DataFormatException — and rethrows RuntimeException('Deflater decompress error'). DataFormatException means the buffer is not valid zlib/deflate data: wrong compressor on the producer, corrupted/truncated payload, or raw bytes passed where compressed bytes were expected. The broad catch also covers premature end-of-stream cases handled by the internal length==0 break.
Source
Thrown at compressor/seata-compressor-deflater/src/main/java/org/apache/seata/compressor/deflater/DeflaterUtil.java:70
if (bytes == null) {
throw new NullPointerException("bytes is null");
}
int length = 0;
Inflater inflater = new Inflater();
inflater.setInput(bytes);
byte[] outputBytes = new byte[BUFFER_SIZE];
try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
while (!inflater.finished()) {
length = inflater.inflate(outputBytes);
if (length == 0) {
break;
}
bos.write(outputBytes, 0, length);
}
inflater.end();
return bos.toByteArray();
} catch (Exception e) {
throw new RuntimeException("Deflater decompress error", e);
}
}
}
View on GitHub (pinned to e01f97c6db)
Solutions
- Set identical compressor configuration on all peers (client transport, server transport, undo_log compressor) and do a synchronized restart/rollout.
- Sanity-check the payload: raw deflate streams from Seata start with a zlib header (first byte usually 0x78); anything else indicates a different algorithm.
- Verify byte-for-byte transport (base64 or safe binary framing) end to end.
- Catch RuntimeException and inspect getCause() — DataFormatException confirms bad data rather than a Seata bug.
Example fix
// before
byte[] raw = DeflaterUtil.decompress(body);
// after
try {
byte[] raw = DeflaterUtil.decompress(body);
} catch (RuntimeException e) {
if (e.getCause() instanceof DataFormatException) {
throw new IOException("payload is not valid deflate data — check compressor config on both peers", e.getCause());
}
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
// zlib streams (JDK Deflater default) typically start with 0x78
public static boolean looksLikeZlib(byte[] data) {
return data != null && data.length >= 2 && data[0] == 0x78;
} Try / catch
try {
return DeflaterUtil.decompress(bytes);
} catch (RuntimeException e) {
if (e.getCause() instanceof java.util.zip.DataFormatException) {
throw new IOException("payload is not valid deflate data — "
+ "check that both peers use the same compressor", e.getCause());
}
throw e;
} Prevention
- Never change seata compressor settings on one side only; plan synchronized restarts.
- Transport compressed bytes as raw binary or base64 — never through lossy text conversions.
- Check DataFormatException in the cause chain to distinguish bad data from environment faults.
When it happens
Trigger: decompress(bytes) where bytes was produced by gzip/bzip2/zstd or not compressed at all (compressor id mismatch between Seata peers), truncated by a size limit, or corrupted in transit; the Inflater constructor rejects the header on first inflate() call.
Common situations: Changing seata compressor settings on the client but not the server (or rolling restart leaving mixed versions); payloads mangled by text-mode transports (e.g. sent as ISO-8859-1 strings); undo logs written before compression enabled then read with deflater on.
Related errors
AI-assisted analysis of apache/incubator-seata@e01f97c6db (2026-08-14).
Data as JSON: /api/errors/04d09e96a0c399f8.
Report an issue: GitHub.