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

  1. Set identical compressor configuration on all peers (client transport, server transport, undo_log compressor) and do a synchronized restart/rollout.
  2. Sanity-check the payload: raw deflate streams from Seata start with a zlib header (first byte usually 0x78); anything else indicates a different algorithm.
  3. Verify byte-for-byte transport (base64 or safe binary framing) end to end.
  4. 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

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.