flowable/flowable-engine · error · FlowableException

IO exception occurred

Error message

IO exception occurred

What it means

When the asynchronous HTTP call completes exceptionally with an IOException, call() unwraps the ExecutionException and rethrows the cause wrapped in a FlowableException with message "IO exception occurred". It signals a transport-level failure of the HTTP request.

Solutions

  1. Inspect the cause chain (getCause()) for the concrete IOException and fix connectivity (host, port, DNS, proxy, TLS).
  2. Retry the request with backoff if the failure is transient (connection reset, timeout).
  3. Catch FlowableException around call() and fall back to an alternative endpoint or error handling path in the flow.

Example fix

// before
HttpResponse response = request.call();

// after
try {
    HttpResponse response = request.call();
} catch (FlowableException e) {
    logger.warn("HTTP IO failure", e);
    // retry or fallback
}
Defensive patterns

Strategy: retry

Try / catch

try {
    HttpResponse response = request.call();
} catch (FlowableException e) {
    Throwable cause = e.getCause();
    if (cause instanceof IOException) {
        // log and retry with exponential backoff, or fail over to backup endpoint
    }
}

Prevention

When it happens

Trigger: callAsync().get() throws ExecutionException whose cause is a java.io.IOException — e.g. connection reset, DNS failure, socket timeout, or stream errors inside the async HTTP client.

Common situations: Target host unreachable or firewall blocking the port; TLS handshake failures; server closing connections; network outages in containerized/Kubernetes environments; wrong proxy configuration.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/e70a41ee6afed91e. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable-http-common/src/main/java/org/flowable/http/common/api/client/AsyncExecutableHttpRequest.java:39

/**
 * @author Filip Hrisafov
 */
public interface AsyncExecutableHttpRequest extends ExecutableHttpRequest {

    @Override
    default HttpResponse call() {
        try {
            return callAsync().get();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new FlowableException("Call was interrupted", e);
        } catch (ExecutionException e) {
            Throwable cause = e.getCause();
            if (cause instanceof RuntimeException) {
                throw (RuntimeException) cause;
            } else if (cause instanceof IOException) {
                throw new FlowableException("IO exception occurred", cause);
            } else {
                throw new FlowableException("execution exception", cause);
            }
        }
    }

    CompletableFuture<HttpResponse> callAsync();
}

View on GitHub (pinned to d6d39ce1c6)