apache/incubator-seata · error · RuntimeException
Zip compress error
Error message
Zip compress error
What it means
Wrapped IOException from ZipUtil.compress thrown as RuntimeException('Zip compress error', e). Although compressing to an in-memory ByteArrayOutputStream rarely fails, ZipOutputStream can throw when the entry state is wrong — e.g. an entry with a preset size that mismatches the written bytes on close, or a nested entry error. The cause chain carries the real IOException.
Source
Thrown at compressor/seata-compressor-zip/src/main/java/org/apache/seata/compressor/zip/ZipUtil.java:47
*/
public class ZipUtil {
private static final int BUFFER_SIZE = 8192;
public static byte[] compress(byte[] bytes) {
if (bytes == null) {
throw new NullPointerException("bytes is null");
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
try (ZipOutputStream zip = new ZipOutputStream(out)) {
ZipEntry entry = new ZipEntry("zip");
entry.setSize(bytes.length);
zip.putNextEntry(entry);
zip.write(bytes);
zip.closeEntry();
return out.toByteArray();
} catch (IOException e) {
throw new RuntimeException("Zip compress error", e);
}
}
public static byte[] decompress(byte[] bytes) {
if (bytes == null) {
throw new NullPointerException("bytes is null");
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
try (ZipInputStream zip = new ZipInputStream(new ByteArrayInputStream(bytes))) {
byte[] buffer = new byte[BUFFER_SIZE];
while (zip.getNextEntry() != null) {
int n;
while ((n = zip.read(buffer)) > -1) {
out.write(buffer, 0, n);
}
}
return out.toByteArray();
} catch (IOException e) {View on GitHub (pinned to e01f97c6db)
Solutions
- Read the cause exception: ZipException with 'incorrect number of bytes' / CRC means size metadata mismatched the data written.
- If you modified ZipUtil, remove the entry.setSize call or keep it exactly equal to bytes.length.
- Wrap the call and treat as non-retryable data error — do not loop retrying compression of the same bytes.
- Check for OOM in logs if payloads are huge; raise heap or switch to a streaming compressor.
Example fix
// before
ZipEntry entry = new ZipEntry("zip");
entry.setSize(bytes.length);
// after (size metadata optional; omit to let JDK compute it)
ZipEntry entry = new ZipEntry("zip"); Defensive patterns
Strategy: try-catch
Try / catch
try {
byte[] zipped = ZipUtil.compress(bytes);
} catch (RuntimeException e) {
// inspect e.getCause() for the underlying IOException; compression of in-memory bytes is non-retryable
LOG.error("zip compress failed", e.getCause());
throw e;
} Prevention
- If you fork ZipUtil, keep entry.setSize exactly equal to the written length or drop it
- Treat compression failures as data errors, not transient ones — do not auto-retry
When it happens
Trigger: entry.setSize(bytes.length) set to a wrong value so finish/close detects a size mismatch; calling compress concurrently on shared state (not the case here, it's per-call); JDK zip implementation errors such as 'ZIP file must have at least one entry' or CRC mismatches on close; extremely large payloads causing OutOfMemoryError-adjacent IO failures.
Common situations: Extending ZipUtil and mutating bytes.length vs actual write length; exotic JVMs or old JDK versions with stricter ZipOutputStream checks; corrupted heap producing inconsistent arrays (rare).
Related errors
AI-assisted analysis of apache/incubator-seata@e01f97c6db (2026-08-14).
Data as JSON: /api/errors/d518df4ebda3d518.
Report an issue: GitHub.