flowable/flowable-engine · error · FlowableException
Error reading image stream
Error message
Error reading image stream
What it means
DecisionImageResource.getImageResource reads the diagram image for a decision; when the image stream is non-null it converts it with IOUtils.toByteArray, and any exception there is wrapped as FlowableException("Error reading image stream", e). A companion FlowableObjectNotFoundException is thrown when the decision simply has no image. This error means the image exists but its bytes could not be read/converted.
Source
Thrown at modules/flowable-dmn-rest/src/main/java/org/flowable/dmn/rest/service/api/repository/DecisionImageResource.java:61
public class DecisionImageResource extends BaseDecisionResource {
@ApiOperation(value = "Get a decision requirements diagram image", tags = { "Decisions" })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Indicates request was successful and the decision requirements diagram image returned"),
@ApiResponse(code = 404, message = "Indicates the requested decision requirements diagram image was not found.")
})
@GetMapping(value = "/dmn-repository/decisions/{decisionId}/image", produces = MediaType.IMAGE_PNG_VALUE)
public ResponseEntity<byte[]> getImageResource(@ApiParam(name = "decisionId") @PathVariable String decisionId) {
DmnDecision decision = getDecisionFromRequest(decisionId);
try (final InputStream imageStream = dmnRepositoryService.getDecisionRequirementsDiagram(decision.getId())) {
if (imageStream != null) {
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.set("Content-Type", MediaType.IMAGE_PNG_VALUE);
try {
return new ResponseEntity<>(IOUtils.toByteArray(imageStream), responseHeaders, HttpStatus.OK);
} catch (Exception e) {
throw new FlowableException("Error reading image stream", e);
}
} else {
throw new FlowableObjectNotFoundException("Decision with id '" + decision.getId() + "' has no image.");
}
} catch (IOException e) {
throw new FlowableException("Error reading image stream", e);
}
}
}
View on GitHub (pinned to d6d39ce1c6)
Solutions
- Log the chained cause (e.getCause()) to identify the actual IO/SQL failure and retry after fixing connectivity.
- Ensure the deployment actually includes the diagram resource; redeploy with the image if missing (avoids the related 'has no image' error).
- If the image blob is corrupted, redeploy the decision resources.
- Increase read timeouts / heap for large diagram resources.
Example fix
// before
ResponseEntity<byte[]> img = client.getDecisionImageResource(decisionId); // FlowableException
// after
try {
return client.getDecisionImageResource(decisionId);
} catch (FlowableObjectNotFoundException e) {
return ResponseEntity.notFound().build(); // decision has no image
} catch (FlowableException e) {
logger.error("image stream failed:", e.getCause());
return retry(() -> client.getDecisionImageResource(decisionId));
} Defensive patterns
Strategy: try-catch
Try / catch
try {
return client.getDecisionImageResource(decisionId);
} catch (FlowableObjectNotFoundException e) {
// 'has no image' -> treat as 404, don't retry
} catch (FlowableException e) {
// 'Error reading image stream' -> check e.getCause(), retry if transient
} Prevention
- Deploy DMN models together with their diagram resources so images always exist
- Distinguish the no-image not-found from the stream-read failure by exception type
- Monitor DB health; log wrapped causes for blob read errors
- Allow adequate timeouts/heap for large diagram resources
When it happens
Trigger: GET of a decision's image resource where IOUtils.toByteArray(imageStream) throws: broken or closed stream from the repository service, database blob read failure, or IOException during conversion. (If the decision has no diagram, the separate 'has no image' FlowableObjectNotFoundException is thrown instead.)
Common situations: DMN resources deployed without diagram resources (callers hitting the no-image 404 path); DB connectivity issues or corrupted image blobs; truncation/timeout reading large PNG resources; upgrading engines where diagram generation settings changed.
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
- Error while reading process diagram image.
- Error converting resource stream
- could not get byte array from resource '${resourceName}'
- Error reading image stream
- Error converting resource stream
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/22789f3341b1521e.
Report an issue: GitHub.