flowable/flowable-engine · error · FlowableException

could not get byte array from resource

Error message

could not get byte array from resource '${resourceName}'

What it means

After reading the supplied InputStream with IOUtils.toByteArray, EventDeploymentBuilderImpl.addInputStream wraps any read failure in this FlowableException, preserving the original exception as the cause. It signals that the resource bytes could not be extracted from the stream.

Solutions

  1. Inspect the cause exception attached to this FlowableException to identify the underlying IO problem
  2. Pass a freshly opened InputStream (do not reuse a consumed/closed stream) for each deployment
  3. If reading a file, verify it exists, is readable, and open it immediately before addInputStream

Example fix

// before
byte[] unused = IOUtils.toByteArray(is); // consumes stream
is.close();
deploymentBuilder.addInputStream(name, is); // already closed
// after
deploymentBuilder.addInputStream(name, new FileInputStream(file)); // fresh stream
Defensive patterns

Strategy: try-catch

Validate before calling

// can be caught; ensure stream is fresh and readable before deploy
try (InputStream is = new FileInputStream(file)) {
    if (is.read() == -1) throw new IllegalStateException("empty resource: " + file);
}

Try / catch

try {
    deploymentBuilder.addInputStream(name, stream);
} catch (FlowableException e) {
    if (e.getMessage().contains("could not get byte array")) {
        // inspect e.getCause() for the underlying IOException and reopen the stream
    } else { throw e; }
}

Prevention

When it happens

Trigger: addInputStream is called with a stream whose read() throws — e.g. a closed stream, a broken file handle, an IO error while reading a network-backed stream — so IOUtils.toByteArray throws inside the try block.

Common situations: Passing an already-consumed or closed InputStream (stream read twice); reading from a temp file deleted mid-deployment; container classloader stream errors; disk/socket IO failures when the resource is remote.

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/2994c045b2e07c38. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable-event-registry/src/main/java/org/flowable/eventregistry/impl/repository/EventDeploymentBuilderImpl.java:61

    public EventDeploymentBuilderImpl() {
        EventRegistryEngineConfiguration eventRegistryEngineConfiguration = CommandContextUtil.getEventRegistryConfiguration();
        this.repositoryService = (EventRepositoryServiceImpl) eventRegistryEngineConfiguration.getEventRepositoryService();
        this.deployment = eventRegistryEngineConfiguration.getDeploymentEntityManager().create();
        this.resourceEntityManager = eventRegistryEngineConfiguration.getResourceEntityManager();
    }

    @Override
    public EventDeploymentBuilder addInputStream(String resourceName, InputStream inputStream) {
        if (inputStream == null) {
            throw new FlowableException("inputStream for resource '" + resourceName + "' is null");
        }

        byte[] bytes = null;
        try {
            bytes = IOUtils.toByteArray(inputStream);
        } catch (Exception e) {
            throw new FlowableException("could not get byte array from resource '" + resourceName + "'", e);
        }

        if (bytes == null) {
            throw new FlowableException("byte array for resource '" + resourceName + "' is null");
        }

        EventResourceEntity resource = resourceEntityManager.create();
        resource.setName(resourceName);
        resource.setBytes(bytes);
        deployment.addResource(resource);
        return this;
    }

    @Override
    public EventDeploymentBuilder addClasspathResource(String resource) {
        try (final InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(resource)) {
            if (inputStream == null) {
                throw new FlowableException("resource '" + resource + "' not found");

View on GitHub (pinned to d6d39ce1c6)