flowable/flowable-engine · error · FlowableException
HTTP
Error message
HTTP${code} What it means
BaseHttpActivityDelegate.saveResponseFields throws FlowableException("HTTP" + code, e.g. "HTTP500" or "HTTP404") when the response status code matches the configured failCodes list (including wildcard 3XX/4XX/5XX entries). It converts configured HTTP failure status codes into a failed Flowable activity so the process can take its error path.
Solutions
- Check the code in the message (e.g. HTTP500) and inspect the remote service logs to fix the server-side problem.
- Fix the HTTP task's request (URL, method, authentication) if the code is 4xx caused by a bad request.
- Adjust the failCodes/`failStatusCodes` configuration on the HTTP activity if the failing code should not be treated as a failure.
- Add a boundary error event on the HTTP service task to handle the failure within the process instead of failing the execution.
Example fix
// before: failCodes = ["5XX"] and any 500 aborts the task // after: only fail on specific codes failCodes = ["503"]; // tolerate 500s, fail only on 503
Defensive patterns
Strategy: try-catch
Validate before calling
// before executing, check code against configured failCodes
boolean willFail(String code, Set<String> failCodes) {
return failCodes.contains(code)
|| (code.startsWith("5") && failCodes.contains("5XX"))
|| (code.startsWith("4") && failCodes.contains("4XX"))
|| (code.startsWith("3") && failCodes.contains("3XX"));
} Try / catch
try {
delegate.execute(execution);
} catch (FlowableException e) {
if (e.getMessage() != null && e.getMessage().startsWith("HTTP")) {
String code = e.getMessage().substring(4);
// handle 4xx/5xx: retry, alert, or route to error boundary path
}
} Prevention
- Add a boundary error event on HTTP service tasks to handle failure status codes in-process
- Validate endpoint URLs, auth and payloads to avoid avoidable 4xx responses
- Configure failCodes/failTimeout deliberately — avoid broad "5XX" unless intended
- Monitor the remote service health before dependent process steps run
When it happens
Trigger: An HTTP activity returns a status code that is listed in failCodes, or whose first digit matches a configured wildcard ("3XX", "4XX", "5XX"), during saveResponseFields handling.
Common situations: Remote REST endpoint returns 500 after a deployment; 404 due to a wrong URL/path in the HTTP task config; 401/403 from expired credentials; misconfigured failCodes (e.g. "5XX") classifying otherwise acceptable responses as failures.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- HTTP_TASK_REQUEST_METHOD_INVALID
- HTTP_TASK_REQUEST_METHOD_REQUIRED
- A delegated task cannot be completed, but should be…
- A request body was expected when bulk updating tasks.
- A request body was expected when bulk updating tasks.
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/590eb48431dde12c.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-http-common/src/main/java/org/flowable/http/common/impl/BaseHttpActivityDelegate.java:204
if (handleCodes != null && !handleCodes.isEmpty()) {
if (handleCodes.contains(code)
|| (code.startsWith("5") && handleCodes.contains("5XX"))
|| (code.startsWith("4") && handleCodes.contains("4XX"))
|| (code.startsWith("3") && handleCodes.contains("3XX"))) {
propagateError(variableContainer, code);
return;
}
}
Set<String> failCodes = request.getFailCodes();
if (failCodes != null && !failCodes.isEmpty()) {
if (failCodes.contains(code)
|| (code.startsWith("5") && failCodes.contains("5XX"))
|| (code.startsWith("4") && failCodes.contains("4XX"))
|| (code.startsWith("3") && failCodes.contains("3XX"))) {
throw new FlowableException("HTTP" + code);
}
}
}
}
}
protected CompletableFuture<ExecutionData> prepareAndExecuteRequest(RequestData request, boolean parallelInSameTransaction, AsyncTaskInvoker taskInvoker) {
ExecutableHttpRequest httpRequest = httpClient.prepareRequest(request.getHttpRequest());
if (!parallelInSameTransaction) {
CompletableFuture<ExecutionData> future = new CompletableFuture<>();
try {
HttpResponse response = httpRequest.call();
future.complete(new ExecutionData(request, response));
} catch (Exception ex) {
future.complete(new ExecutionData(request, null, ex));
}View on GitHub (pinned to d6d39ce1c6)