flowable/flowable-engine · error · FlowableException

IO exception occurred

Error message

IO exception occurred

What it means

`prepareRequest` in the HttpClient 5.x client also catches `IOException` while assembling the request (e.g. building/serializing the request entity such as form or multipart bodies) and rethrows it as `FlowableException("IO exception occurred", cause)`. Unlike error 3001 this fires during request preparation, not execution.

Solutions

  1. Inspect the chained cause to identify the underlying stream/encoding failure.
  2. Ensure any files/streams referenced by request bodies exist and are readable for the lifetime of the request.
  3. For multipart requests, confirm content lengths fit memory — the client serializes the multipart entity into a byte array.
  4. Retry transient failures only after confirming the input data is stable.
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure body sources are readable and fully materialized before the call
Objects.requireNonNull(bodyBytes, "multipart part bytes must be non-null");
// charset sanity check
Charset.forName(charsetName);

Try / catch

try {
    request = client.prepareRequest(requestInfo);
} catch (FlowableException e) {
    if ("IO exception occurred".equals(e.getMessage()) && e.getCause() instanceof IOException io) {
        log.error("Request assembly failed: {}", io.getMessage(), io);
    }
    throw e;
}

Prevention

When it happens

Trigger: `prepareRequest()` throws an `IOException` while setting headers/request entity — e.g. writing the multipart entity byte stream or reading body content fails during request construction.

Common situations: Multipart bodies backed by streams/files that disappear mid-serialization; charset encoding failures on body content; out-of-memory-style stream failures during entity building.

Related errors


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

Appendix: source

Thrown at modules/flowable-http-common/src/main/java/org/flowable/http/common/impl/apache/client5/ApacheHttpComponents5FlowableHttpClient.java:234

                    break;
                }
                case "OPTIONS": {
                    request = AsyncRequestBuilder.options(uri);
                    break;
                }
                default: {
                    throw new FlowableException(requestInfo.getMethod() + " HTTP method not supported");
                }
            }

            setHeaders(request, requestInfo.getHttpHeaders());
            setHeaders(request, requestInfo.getSecureHttpHeaders());

            return new ApacheHttpComponentsExecutableHttpRequest(request.build(), createRequestConfig(requestInfo));
        } catch (URISyntaxException ex) {
            throw new FlowableException("Invalid URL exception occurred", ex);
        } catch (IOException ex) {
            throw new FlowableException("IO exception occurred", ex);
        }
    }

    protected URI createUri(String url) throws URISyntaxException {
        String uri = SPACE_CHARACTER_PATTERN.matcher(url).replaceAll(ENCODED_SPACE_CHARACTER);
        return new URI(PLUS_CHARACTER_PATTERN.matcher(uri).replaceAll(ENCODED_PLUS_CHARACTER));
    }

    protected void setRequestEntity(HttpRequest requestInfo, AsyncRequestBuilder requestBase) throws UnsupportedEncodingException {
        if (requestInfo.getBody() != null) {
            if (StringUtils.isNotEmpty(requestInfo.getBodyEncoding())) {
                requestBase.setEntity(AsyncEntityProducers.create(requestInfo.getBody(), Charset.forName(requestInfo.getBodyEncoding())));
            } else {
                requestBase.setEntity(AsyncEntityProducers.create(requestInfo.getBody()));
            }
        } else if (requestInfo.getBodyBytes() != null) {
            // A caller-supplied Content-Type header (added afterwards) takes precedence over this default.
            requestBase.setEntity(requestInfo.getBodyBytes(), ContentType.APPLICATION_OCTET_STREAM);

View on GitHub (pinned to d6d39ce1c6)