flowable/flowable-engine · error · ActivitiIllegalArgumentException

couldn't open resource stream: ${message}

Error message

couldn't open resource stream: ${message}

What it means

buildProcessEngine opens the flowable.cfg.xml URL stream to construct the engine; if openStream throws IOException the initializer throws this ActivitiIllegalArgumentException with the IO error message. The resource URL existed but its content could not be read.

Source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/ProcessEngines.java:179

            processEngineInfosByName.put(processEngineName, processEngineInfo);
        } catch (Throwable e) {
            LOGGER.error("Exception while initializing process engine: {}", e.getMessage(), e);
            processEngineInfo = new ProcessEngineInfoImpl(null, resourceUrlString, ExceptionUtils.getStackTrace(e));
        }
        processEngineInfosByResourceUrl.put(resourceUrlString, processEngineInfo);
        processEngineInfos.add(processEngineInfo);
        return processEngineInfo;
    }

    private static ProcessEngine buildProcessEngine(URL resource) {
        InputStream inputStream = null;
        try {
            inputStream = resource.openStream();
            ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createProcessEngineConfigurationFromInputStream(inputStream);
            return processEngineConfiguration.buildProcessEngine();

        } catch (IOException e) {
            throw new ActivitiIllegalArgumentException("couldn't open resource stream: " + e.getMessage(), e);
        } finally {
            IoUtil.closeSilently(inputStream);
        }
    }

    /**
     * Get initialization results.
     */
    public static List<ProcessEngineInfo> getProcessEngineInfos() {
        return processEngineInfos;
    }

    /**
     * Get initialization results. Only info will we available for process engines which were added in the {@link ProcessEngines#init()}. No {@link ProcessEngineInfo} is available for engines which
     * were registered programmatically.
     */
    public static ProcessEngineInfo getProcessEngineInfo(String processEngineName) {
        return processEngineInfosByName.get(processEngineName);

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Verify the JAR/directory containing flowable.cfg.xml is intact and readable (unzip -t)
  2. Re-deploy the application artifact containing the config file
  3. Check file permissions and that the resource is not on an unreachable remote classpath entry
  4. Load the engine explicitly from a filesystem path you control to bypass the failing classpath entry

Example fix

// before
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine(); // fails reading bad classpath entry
// after
ProcessEngine engine = ProcessEngineConfiguration
    .createProcessEngineConfigurationFromResource("/etc/app/flowable.cfg.xml")
    .buildProcessEngine();
Defensive patterns

Strategy: validation

Validate before calling

URL cfg = getClass().getClassLoader().getResource("flowable.cfg.xml");
try (InputStream in = cfg.openStream()) {
  if (in.read() == -1) throw new IllegalStateException("flowable.cfg.xml is empty/unreadable");
} catch (IOException e) {
  throw new IllegalStateException("config resource unreadable: " + cfg, e);
}

Try / catch

try {
  engine = ProcessEngines.getDefaultProcessEngine();
} catch (ActivitiIllegalArgumentException e) {
  if (e.getMessage().startsWith("couldn't open resource stream"))
    engine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("flowable.cfg.xml").buildProcessEngine();
  else throw e;
}

Prevention

When it happens

Trigger: A flowable.cfg.xml URL found on the classpath (e.g. inside a JAR, remote URL, or file that vanished) cannot be opened via resource.openStream().

Common situations: Corrupted or partially deployed JARs containing flowable.cfg.xml; files deleted between discovery and read; unreadable permissions; network classpath resources going offline.

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/63d359740b28ade3. Report an issue: GitHub.