flowable/flowable-engine · error · FlowableException
Unexpected exception getting variable data
Error message
Unexpected exception getting variable data
What it means
This FlowableException wraps an IOException that occurred while reading the binary content stream of a historic case instance variable. Flowable stores binary variables as byte arrays on disk or in the database; streaming that content back through the REST API can fail on I/O. It signals a server-side data-read problem, not a client request error.
Source
Thrown at modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/history/caze/HistoricCaseInstanceVariableDataResource.java:87
result = (byte[]) variable.getValue();
response.setContentType("application/octet-stream");
} else if (CmmnRestResponseFactory.SERIALIZABLE_VARIABLE_TYPE.equals(variable.getType())) {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
ObjectOutputStream outputStream = new ObjectOutputStream(buffer);
outputStream.writeObject(variable.getValue());
outputStream.close();
result = buffer.toByteArray();
response.setContentType("application/x-java-serialized-object");
} else {
throw new FlowableObjectNotFoundException("The variable does not have a binary data stream.", null);
}
return result;
} catch (IOException ioe) {
// Re-throw IOException
throw new FlowableException("Unexpected exception getting variable data", ioe);
}
}
public RestVariable getVariableFromRequest(boolean includeBinary, String caseInstanceId, String variableName) {
HistoricCaseInstance caseObject = getHistoricCaseInstanceFromRequest(caseInstanceId);
HistoricVariableInstance variable = historyService.createHistoricVariableInstanceQuery()
.caseInstanceId(caseObject.getId())
.variableName(variableName)
.singleResult();
if (variable == null || variable.getValue() == null) {
throw new FlowableObjectNotFoundException("Historic case instance '" + caseInstanceId + "' variable value for " + variableName + " couldn't be found.", VariableInstanceEntity.class);
} else {
return restResponseFactory.createRestVariable(variableName, variable.getValue(), null, caseInstanceId, CmmnRestResponseFactory.VARIABLE_HISTORY_CASE, includeBinary);
}
}
}View on GitHub (pinned to d6d39ce1c6)
Solutions
- Check the server logs for the wrapped IOException cause (getCause()) and fix the underlying storage/DB issue first.
- Verify the variable's blob/bytearray row still exists and is not corrupted in the ACT_GE_BYTEARRAY table.
- If the variable is a serialized POJO, confirm the class is present on the server classpath and is Serializable.
- Restore database or content-store connectivity, then retry the request.
- If the blob is unrecoverable, delete and recreate the data or exclude binary variables from the history query.
Example fix
// before
return result; // stream read may throw IOException
// after
try (InputStream content = result) {
return IOUtils.toByteArray(content);
} catch (IOException e) {
throw new FlowableException("Unexpected exception getting variable data", e);
} Defensive patterns
Strategy: try-catch
Validate before calling
// Java: list variables first via GET /cmmn-history/historic-case-instances/{id}/variables
// and check the variable's type is binary/serializable before requesting /data Type guard
boolean isBinaryVariable(RestVariable v) {
return v != null && ("binary".equals(v.getType()) || "serializable".equals(v.getType()));
} Try / catch
try {
byte[] data = restClient.getVariableData(caseId, varName);
} catch (RestClientException e) {
log.error("Failed to read binary variable data", e);
// surface a generic 'variable data unavailable' to the user
} Prevention
- Always inspect the wrapped cause (FlowableException.getCause()) in server logs.
- Monitor DB/content-store health; binary reads fail first when storage degrades.
- Keep serialized variable classes stable and on the server classpath.
- Avoid storing huge blobs as process variables; use external storage references.
When it happens
Trigger: GET /cmmn-history/historic-case-instances/{caseInstanceId}/variables/{variableName}/data when the variable is a binary/serializable type and reading its content stream throws IOException (corrupt blob, missing file in content store, DB connection dropped mid-stream).
Common situations: Binary variable blobs deleted or truncated outside Flowable's transactional control; database unavailable or connection reset; serialized Java objects whose classes are no longer on the server classpath; disk full on content stores backed by the filesystem.
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 converting resource stream
- Error converting resource stream
- Could not find a resource with id '<resourceName>' in deploy
- <e.getMessage()>
- Could not find an app deployment with id '<deploymentId>
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/42d0c42601503f99.
Report an issue: GitHub.