flowable/flowable-engine · error · org.activiti.engine.ActivitiException

problem reading zip input stream

Error message

problem reading zip input stream

What it means

addZipInputStream iterates zip entries and adds each as a deployment resource. Any exception while reading the stream (corrupt archive, truncated download, closed stream, unsupported compression) is caught and rethrown as an ActivitiException wrapping the original cause.

Source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/repository/DeploymentBuilderImpl.java:103

    }

    @Override
    public DeploymentBuilder addZipInputStream(ZipInputStream zipInputStream) {
        try {
            ZipEntry entry = zipInputStream.getNextEntry();
            while (entry != null) {
                if (!entry.isDirectory()) {
                    String entryName = entry.getName();
                    byte[] bytes = IoUtil.readInputStream(zipInputStream, entryName);
                    ResourceEntity resource = new ResourceEntity();
                    resource.setName(entryName);
                    resource.setBytes(bytes);
                    deployment.addResource(resource);
                }
                entry = zipInputStream.getNextEntry();
            }
        } catch (Exception e) {
            throw new ActivitiException("problem reading zip input stream", e);
        }
        return this;
    }

    @Override
    public DeploymentBuilder addBpmnModel(String resourceName, BpmnModel bpmnModel) {
        BpmnXMLConverter bpmnXMLConverter = new BpmnXMLConverter();
        String bpmn20Xml = new String(bpmnXMLConverter.convertToXML(bpmnModel), StandardCharsets.UTF_8);
        addString(resourceName, bpmn20Xml);
        return this;
    }

    @Override
    public DeploymentBuilder name(String name) {
        deployment.setName(name);
        return this;
    }

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Inspect the wrapped cause exception (e.getCause()) to see the underlying IO or zip error.
  2. Validate the zip/bar archive opens with a normal unzip tool before deploying.
  3. Ensure the stream is fresh and readable at call time; do not reuse a consumed stream.
  4. Re-download or regenerate the archive; verify file integrity (size, checksum) after transfer.

Example fix

// before
builder.addZipInputStream(new ZipInputStream(new FileInputStream(zipFile)));
// after
try (ZipInputStream zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(zipFile)))) {
    builder.addZipInputStream(zis);
} catch (ActivitiException e) {
    logger.error("bad archive: " + e.getCause(), e);
    throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

File f = new File(zipPath);
if (!f.isFile() || f.length() == 0) throw new IllegalStateException("archive missing or empty: " + zipPath);

Try / catch

try {
    builder.addZipInputStream(zis);
} catch (ActivitiException e) {
    logger.error("zip deploy failed: " + e.getCause(), e);
    throw new DeploymentException(e);
}

Prevention

When it happens

Trigger: Calling DeploymentBuilder.addZipInputStream(ZipInputStream) with a stream whose underlying data is corrupted, truncated, or fails mid-read (IOException or any other Exception inside the entry loop).

Common situations: Uploading a bar/zip file that was truncated during transfer, a zip built with an unsupported algorithm, passing a stream that was already fully consumed, network interruption while streaming a remote archive.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/b4ae8498e5f20650. Report an issue: GitHub.