flowable/flowable-engine · error · FlowableException

Cannot create multi part entity

Error message

Cannot create multi part entity

What it means

After assembling the multipart entity, the HttpClient 5.x client serializes it: `multiPartEntity.writeTo(outputStream)` writes the fully formed multipart body into a `ByteArrayOutputStream`. An `IOException` during this in-memory serialization is wrapped as `FlowableException("Cannot create multi part entity", e)`.

Source

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

                        entityBuilder.addBinaryBody(name, (byte[]) value, ContentType.DEFAULT_BINARY, part.getFilename());
                    }
                } else if (value instanceof String) {
                    if (StringUtils.isNotBlank(part.getMimeType())) {
                        entityBuilder.addTextBody(name, (String) value, ContentType.create(part.getMimeType()));
                    } else {
                        entityBuilder.addTextBody(name, (String) value);
                    }
                } else if (value != null) {
                    throw new FlowableIllegalArgumentException("Value of type " + value.getClass() + " is not supported as multi part content");
                }
            }

            try (HttpEntity multiPartEntity = entityBuilder.build();
                 ByteArrayOutputStream outputStream = new ByteArrayOutputStream((int) multiPartEntity.getContentLength())) {
                multiPartEntity.writeTo(outputStream);
                requestBase.setEntity(outputStream.toByteArray(), ContentType.parse(multiPartEntity.getContentType()));
            } catch (IOException e) {
                throw new FlowableException("Cannot create multi part entity", e);
            }
        } else if (requestInfo.getFormParameters() != null) {
            Map<String, List<String>> formParameters = requestInfo.getFormParameters();
            List<BasicNameValuePair> parameters = new ArrayList<>(formParameters.size());
            for (Map.Entry<String, List<String>> entry : formParameters.entrySet()) {
                String name = entry.getKey();
                for (String value : entry.getValue()) {
                    parameters.add(new BasicNameValuePair(name, value));
                }
            }

            Charset charset = requestInfo.getBodyEncoding() != null ? Charset.forName(requestInfo.getBodyEncoding()) : null;

            String formParametersString = WWWFormCodec.format(parameters, charset);
            requestBase.setEntity(AsyncEntityProducers.create(formParametersString, ContentType.APPLICATION_FORM_URLENCODED.withCharset(charset)));
        }
    }

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Inspect the chained cause for the underlying stream failure and fix the part data source.
  2. Ensure part values are fully materialized, stable `String`/`byte[]` values (not live streams).
  3. Reduce multipart payload size — the entire entity is buffered in memory before the request is sent.
  4. Upgrade/verify httpmime and httpclient5 versions if the entity's writeTo fails due to a library bug.
Defensive patterns

Strategy: try-catch

Validate before calling

// keep total multipart payload well under Integer.MAX_VALUE since it is buffered in memory
long estimated = parts.values().stream().mapToLong(v -> v instanceof byte[] b ? b.length : String.valueOf(v).length()).sum();
if (estimated > 64 * 1024 * 1024) {
    throw new IllegalStateException("Multipart payload too large for in-memory serialization: " + estimated + " bytes");
}

Try / catch

try {
    return client.call(requestInfo);
} catch (FlowableException e) {
    if ("Cannot create multi part entity".equals(e.getMessage()) && e.getCause() != null) {
        log.error("Multipart serialization failed: {}", e.getCause().getMessage(), e.getCause());
    }
    throw e;
}

Prevention

When it happens

Trigger: `setRequestEntity()` fails when `multiPartEntity.writeTo(outputStream)` or `multiPartEntity.getContentLength()` throws — typically because a part's backing content stream fails while being read/written.

Common situations: Part content backed by a closed or broken stream; content length overflow (entity larger than `Integer.MAX_VALUE` used for the ByteArrayOutputStream initial size); charset/encoding issues on part content.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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