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

  1. Check the code in the message (e.g. HTTP500) and inspect the remote service logs to fix the server-side problem.
  2. Fix the HTTP task's request (URL, method, authentication) if the code is 4xx caused by a bad request.
  3. Adjust the failCodes/`failStatusCodes` configuration on the HTTP activity if the failing code should not be treated as a failure.
  4. 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

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


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)