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)`.

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.

Appendix: 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)