flowable/flowable-engine · error · FlowableException

org.apache.http.entity.mime.MultipartEntityBuilder is not…

Error message

org.apache.http.entity.mime.MultipartEntityBuilder is not present on the classpath. Multi value parts cannot be used. If you want to use, please make sure that the org.apache.httpcomponents:httpmime dependency is available

What it means

Flowable's Apache HttpClient 4.x based HTTP client supports multi-value multipart request bodies only when the optional `org.apache.httpcomponents:httpmime` artifact is on the classpath. `MultipartEntityBuilder` lives in that optional dependency; when it is absent, `setRequestEntity` refuses to build multipart requests rather than failing later with a NoClassDefFoundError. This is an explicit, early capability check.

Solutions

  1. Add the dependency: Maven `org.apache.httpcomponents:httpmime` (version matching your httpclient 4.x), or Gradle `implementation 'org.apache.httpcomponents:httpmime:4.5.14'`.
  2. If you do not need multipart bodies, stop sending multi value part parameters in the HTTP task/request configuration and use body/form parameters instead.
  3. Verify with `mvn dependency:tree | grep httpmime` (or Gradle equivalent) that httpmime is actually resolved into the runtime classpath, not marked provided/optional.

Example fix

// before (pom.xml) - httpclient without httpmime
<dependency>
  <groupId>org.apache.httpcomponents</groupId>
  <artifactId>httpclient</artifactId>
  <version>4.5.14</version>
</dependency>

// after - add the optional httpmime dependency
<dependency>
  <groupId>org.apache.httpcomponents</groupId>
  <artifactId>httpclient</artifactId>
  <version>4.5.14</version>
</dependency>
<dependency>
  <groupId>org.apache.httpcomponents</groupId>
  <artifactId>httpmime</artifactId>
  <version>4.5.14</version>
</dependency>
Defensive patterns

Strategy: validation

Validate before calling

boolean multipartSupported;
try {
  Class.forName("org.apache.http.entity.mime.MultipartEntityBuilder");
  multipartSupported = true;
} catch (ClassNotFoundException e) {
  multipartSupported = false;
}
if (requestInfo.getMultiValuePartParameters() != null && !requestInfo.getMultiValuePartParameters().isEmpty() && !multipartSupported) {
  throw new IllegalStateException("Add org.apache.httpcomponents:httpmime to the classpath before using multi value parts");
}

Try / catch

try {
    response = client.call(requestInfo);
} catch (FlowableException e) {
    if (e.getMessage() != null && e.getMessage().contains("MultipartEntityBuilder")) {
        // fall back to form parameters or fail fast with a config hint
    }
}

Prevention

When it happens

Trigger: Calling `call()`/`prepareRequest()` on an `ApacheHttpComponentsFlowableHttpClient` with a `FlowableHttpRequestInfo` whose `multiValuePartParameters` (multi value parts) is non-empty while `org.apache.http.entity.mime.MultipartEntityBuilder` is not resolvable on the classpath.

Common situations: Using `flowable-http` in a Spring Boot app without adding httpmime; relying on a transitive httpclient dependency that excludes httpmime; upgrading to httpclient 5.x where the artifact coordinates changed (`org.apache.httpcomponents.client5:httpclient5`), leaving the old optional dep out.

Understand the failure class

Background: "X is not installed. Please install it with pip install Y": missing optional dependency errors — ImportError/ValueError raised when a library's optional extra was never installed — this error's family across 22 libraries.

Related errors


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

Appendix: source

Thrown at modules/flowable-http-common/src/main/java/org/flowable/http/common/impl/apache/ApacheHttpComponentsFlowableHttpClient.java:279

                    if (value instanceof byte[]) {
                        if (StringUtils.isNotBlank(part.getMimeType())) {
                            entityBuilder.addBinaryBody(name, (byte[]) value, ContentType.create(part.getMimeType()), part.getFilename());
                        } else {
                            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");
                    }
                }
                requestBase.setEntity(entityBuilder.build());
            } else {
                throw new FlowableException("org.apache.http.entity.mime.MultipartEntityBuilder is not present on the classpath."
                        + " Multi value parts cannot be used."
                        + " If you want to use, please make sure that the org.apache.httpcomponents:httpmime dependency is available");
            }

        } 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));
                }
            }

            if (StringUtils.isNotEmpty(requestInfo.getBodyEncoding())) {
                requestBase.setEntity(new UrlEncodedFormEntity(parameters, requestInfo.getBodyEncoding()));
            } else {
                requestBase.setEntity(new UrlEncodedFormEntity(parameters));

View on GitHub (pinned to d6d39ce1c6)