{"record":{"id":"d518df4ebda3d518","repo":"apache/incubator-seata","slug":"zip-compress-error","errorCode":null,"errorMessage":"Zip compress error","messagePattern":"Zip compress error","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"compressor/seata-compressor-zip/src/main/java/org/apache/seata/compressor/zip/ZipUtil.java","lineNumber":47,"sourceCode":" */\npublic class ZipUtil {\n\n    private static final int BUFFER_SIZE = 8192;\n\n    public static byte[] compress(byte[] bytes) {\n        if (bytes == null) {\n            throw new NullPointerException(\"bytes is null\");\n        }\n        ByteArrayOutputStream out = new ByteArrayOutputStream();\n        try (ZipOutputStream zip = new ZipOutputStream(out)) {\n            ZipEntry entry = new ZipEntry(\"zip\");\n            entry.setSize(bytes.length);\n            zip.putNextEntry(entry);\n            zip.write(bytes);\n            zip.closeEntry();\n            return out.toByteArray();\n        } catch (IOException e) {\n            throw new RuntimeException(\"Zip compress error\", e);\n        }\n    }\n\n    public static byte[] decompress(byte[] bytes) {\n        if (bytes == null) {\n            throw new NullPointerException(\"bytes is null\");\n        }\n        ByteArrayOutputStream out = new ByteArrayOutputStream();\n        try (ZipInputStream zip = new ZipInputStream(new ByteArrayInputStream(bytes))) {\n            byte[] buffer = new byte[BUFFER_SIZE];\n            while (zip.getNextEntry() != null) {\n                int n;\n                while ((n = zip.read(buffer)) > -1) {\n                    out.write(buffer, 0, n);\n                }\n            }\n            return out.toByteArray();\n        } catch (IOException e) {","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/apache/incubator-seata/blob/e01f97c6db397165050caa6764020410c2c8199a/compressor/seata-compressor-zip/src/main/java/org/apache/seata/compressor/zip/ZipUtil.java#L29-L65","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","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."],"exampleFix":"// before\nZipEntry entry = new ZipEntry(\"zip\");\nentry.setSize(bytes.length);\n\n// after (size metadata optional; omit to let JDK compute it)\nZipEntry entry = new ZipEntry(\"zip\");","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    byte[] zipped = ZipUtil.compress(bytes);\n} catch (RuntimeException e) {\n    // inspect e.getCause() for the underlying IOException; compression of in-memory bytes is non-retryable\n    LOG.error(\"zip compress failed\", e.getCause());\n    throw e;\n}","preventionTips":["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"],"tags":["zip","compression","io","seata"],"backgroundTag":null,"analyzedSha":"e01f97c6db397165050caa6764020410c2c8199a","analyzedAt":"2026-08-14T10:23:53.097Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}