flowable/flowable-engine · error · FlowableException

Failed to read resource ${resource}

Error message

Failed to read resource ${resource}

What it means

FlowableException thrown when an IOException occurs while the classpath resource stream is being opened or read inside addClasspathResource. Unlike the 'not found' case, the resource was locatable but reading its bytes failed. The original IOException is attached as the cause.

Source

Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/repository/CmmnDeploymentBuilderImpl.java:82

        }

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

    @Override
    public CmmnDeploymentBuilder addClasspathResource(String resource) {
        try (final InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(resource)) {
            if (inputStream == null) {
                throw new FlowableException("resource '" + resource + "' not found");
            }
            return addInputStream(resource, inputStream);
            
        } catch (IOException ex) {
            throw new FlowableException("Failed to read resource " + resource, ex);
        }
    }

    @Override
    public CmmnDeploymentBuilder addString(String resourceName, String text) {
        if (text == null) {
            throw new FlowableException("text is null");
        }

        CmmnResourceEntity resource = resourceEntityManager.create();
        resource.setName(resourceName);
        resource.setBytes(text.getBytes(StandardCharsets.UTF_8));
        deployment.addResource(resource);
        return this;
    }
    
    @Override
    public CmmnDeploymentBuilder addBytes(String resourceName, byte[] bytes) {

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Inspect the wrapped IOException cause for the underlying read failure
  2. Rebuild/redeploy the artifact — the jar containing the resource may be corrupted
  3. Verify classloader behavior if using a custom or framework-provided classloader
  4. Retry after fixing environment issues (disk full, file locks)

Example fix

try {
    repositoryService.createDeployment().addClasspathResource("processes/order.cmmn.xml");
} catch (FlowableException e) {
    logger.error("Resource read failed", e.getCause()); // inspect the wrapped IOException
}
Defensive patterns

Strategy: try-catch

Validate before calling

try (InputStream is = getClass().getClassLoader().getResourceAsStream(resource)) {
    if (is != null) { is.readAllBytes(); } // force read to surface IO problems early
}

Try / catch

try {
    builder.addClasspathResource(resource);
} catch (FlowableException e) {
    Throwable cause = e.getCause();
    if (cause instanceof IOException) {
        logger.error("Failed reading CMMN resource {}: {}", resource, cause.getMessage());
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling addClasspathResource(resource) where the underlying resource stream cannot be read — e.g. IO errors opening a jar-backed resource, a corrupted jar on the classpath, or a broken custom ClassLoader implementation.

Common situations: Corrupted or concurrently replaced jar/war in the app server, custom classloader that throws on getResourceAsStream, filesystem/disk errors in containerized environments.

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/7261bd1b12f6353b. Report an issue: GitHub.