{"record":{"id":"560bf5cf9f61e196","repo":"flowable/flowable-engine","slug":"error-while-reading-process-diagram-image","errorCode":null,"errorMessage":"Error while reading process diagram image.","messagePattern":"Error while reading process diagram image\\.","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/diagram/ProcessDiagramLayoutFactory.java","lineNumber":192,"sourceCode":"\n        DiagramNode diagramBounds = new DiagramNode(\"BPMNDiagram\");\n        diagramBounds.setX(minX);\n        diagramBounds.setY(minY);\n        diagramBounds.setWidth(maxX - minX);\n        diagramBounds.setHeight(maxY - minY);\n        return diagramBounds;\n    }\n\n    protected DiagramNode getDiagramBoundsFromImage(InputStream imageStream) {\n        return getDiagramBoundsFromImage(imageStream, 0, 0);\n    }\n\n    protected DiagramNode getDiagramBoundsFromImage(InputStream imageStream, int offsetTop, int offsetBottom) {\n        BufferedImage image;\n        try {\n            image = ImageIO.read(imageStream);\n        } catch (IOException e) {\n            throw new FlowableException(\"Error while reading process diagram image.\", e);\n        }\n        DiagramNode diagramBoundsImage = getDiagramBoundsFromImage(image, offsetTop, offsetBottom);\n        return diagramBoundsImage;\n    }\n\n    protected DiagramNode getDiagramBoundsFromImage(BufferedImage image, int offsetTop, int offsetBottom) {\n        int width = image.getWidth();\n        int height = image.getHeight();\n\n        Map<Integer, Boolean> rowIsWhite = new TreeMap<>();\n        Map<Integer, Boolean> columnIsWhite = new TreeMap<>();\n\n        for (int row = 0; row < height; row++) {\n            if (!rowIsWhite.containsKey(row)) {\n                rowIsWhite.put(row, true);\n            }\n            if (row <= offsetTop || row > image.getHeight() - offsetBottom) {\n                rowIsWhite.put(row, true);","sourceCodeStart":174,"sourceCodeEnd":210,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/diagram/ProcessDiagramLayoutFactory.java#L174-L210","documentation":"getDiagramBoundsFromImage reads the process diagram image via ImageIO.read to compute diagram bounds. If the stream cannot be read (IOException), Flowable wraps it in this FlowableException. Note ImageIO.read returns null (not an exception) for unsupported formats — that failure surfaces later as an NPE.","triggerScenarios":"getBpmnProcessDiagramLayout (or the recursive/diagramBoundsImage paths) receives an image stream that throws IOException when read — closed stream, network failure mid-read, truncated file.","commonSituations":"Passing an already-consumed InputStream; a diagram URL/stream that broke mid-download; corrupted image files in the deployment; unsupported image formats (which yield null from ImageIO.read instead).","solutions":["Ensure the image InputStream is fresh, open, and fully readable before passing it in","Re-fetch the diagram resource from the repository instead of reusing a consumed stream","Verify the image file is a valid, non-truncated PNG/JPEG/GIF that ImageIO can decode","Check the wrapped IOException cause for the underlying I/O problem (network, permissions, disk)"],"exampleFix":"// before\nbyte[] cached = imageBytes; factory.getProcessDiagramLayout(xml, new ByteArrayInputStream(cached));\n\n// after: re-read resource bytes fresh from the repository\nResourceEntity res = repositoryService.getResource(deploymentId, resourceName);\nfactory.getProcessDiagramLayout(xmlStream, new ByteArrayInputStream(res.getBytes()));","handlingStrategy":"validation","validationCode":"if (imageStream == null || imageStream.available() <= 0) {\n    throw new IllegalArgumentException(\"Diagram image stream is empty or closed\");\n}\nBufferedImage img = ImageIO.read(new BufferedInputStream(imageStream)); // also detect unsupported formats (null result)","typeGuard":null,"tryCatchPattern":"try {\n    layout = factory.getProcessDiagramLayout(xmlStream, imageStream);\n} catch (FlowableException e) {\n    if (e.getMessage().equals(\"Error while reading process diagram image.\")) {\n        // re-open/re-fetch the image stream and retry once\n    }\n}","preventionTips":["Always pass a fresh, un-consumed InputStream for the diagram","Use PNG/JPEG/GIF formats ImageIO can decode","Verify image resources in deployments are not truncated"],"tags":["image","io","diagram","stream"],"backgroundTag":"file-read-failed","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}