{"record":{"id":"d6ddcc27ba7910e0","repo":"flowable/flowable-engine","slug":"couldn-t-open-resource-stream-e-getmessage-d6ddcc","errorCode":null,"errorMessage":"couldn't open resource stream: ${e.getMessage()}","messagePattern":"couldn't open resource stream: (.+?)","errorType":"exception","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/ProcessEngines.java","lineNumber":183,"sourceCode":"            processEngineInfosByName.put(processEngineName, processEngineInfo);\n        } catch (Throwable e) {\n            LOGGER.error(\"Exception while initializing process engine: {}\", e.getMessage(), e);\n            processEngineInfo = new EngineInfo(null, resourceUrlString, ExceptionUtils.getStackTrace(e));\n        }\n        processEngineInfosByResourceUrl.put(resourceUrlString, processEngineInfo);\n        processEngineInfos.add(processEngineInfo);\n        return processEngineInfo;\n    }\n\n    private static ProcessEngine buildProcessEngine(URL resource) {\n        InputStream inputStream = null;\n        try {\n            inputStream = resource.openStream();\n            ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createProcessEngineConfigurationFromInputStream(inputStream);\n            return processEngineConfiguration.buildProcessEngine();\n\n        } catch (IOException e) {\n            throw new FlowableIllegalArgumentException(\"couldn't open resource stream: \" + e.getMessage(), e);\n        } finally {\n            IoUtil.closeSilently(inputStream);\n        }\n    }\n\n    /** Get initialization results. */\n    public static List<EngineInfo> getProcessEngineInfos() {\n        return processEngineInfos;\n    }\n\n    /**\n     * Get initialization results. Only info will we available for process engines which were added in the {@link ProcessEngines#init()}. No {@link EngineInfo} is available for engines which were\n     * registered programmatically.\n     */\n    public static EngineInfo getProcessEngineInfo(String processEngineName) {\n        return processEngineInfosByName.get(processEngineName);\n    }\n","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/ProcessEngines.java#L165-L201","documentation":"ProcessEngines.buildProcessEngine(URL resource) opens the configuration resource stream; if openStream() throws IOException the engine cannot be built, so the code throws FlowableIllegalArgumentException with the IOException's message. This usually means the resource URL is unreachable (file deleted, host down, jar repacked).","triggerScenarios":"Calling ProcessEngines.getProcessEngine(name) (or retry(resourceUrl)) for an engine whose config URL no longer resolves — e.g. the flowable.cfg.xml was inside an exploded webapp that was redeployed, or a jar: URL points to a removed jar.","commonSituations":"Stale EngineInfo entries after hot redeploy; remote URLs pointing at moved config files; file permissions preventing read; container cleaned the temp/exploaded directory.","solutions":["Verify the resource URL is still reachable (open it in a browser/curl) and restore or redeploy the missing file","Use ProcessEngines.retry(resourceUrl) after restoring the resource, or call ProcessEngines.destroy() and re-init to refresh the URL list","If using file URLs, ensure the process has read permission on the config file","Build the engine programmatically instead of URL-based discovery"],"exampleFix":"// before\nEngineInfo info = ProcessEngines.getProcessEngineInfo(\"default\");\nProcessEngine engine = info == null ? null : ProcessEngines.getProcessEngine(info.getName());\n\n// after (re-init after redeploy)\nProcessEngines.destroy();\nProcessEngine engine = ProcessEngines.getDefaultProcessEngine();","handlingStrategy":"try-catch","validationCode":"URL u = new URL(resourceUrl);\ntry (InputStream is = u.openStream()) {\n    if (is.read() == -1) throw new IllegalStateException(\"empty config resource: \" + resourceUrl);\n}","typeGuard":null,"tryCatchPattern":"try {\n    ProcessEngines.retry(resourceUrl);\n} catch (FlowableIllegalArgumentException e) {\n    // resource stream unopenable: restore/redeploy the config file, then ProcessEngines.destroy() and re-init\n}","preventionTips":["Keep configuration resources in stable jars/directories not wiped on redeploy","Re-run ProcessEngines.destroy()/init after deployments instead of holding stale EngineInfo URLs"],"tags":["flowable","resource","engine-init","classpath"],"backgroundTag":"file-open-failed","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}