flowable/flowable-engine · error · FlowableIllegalArgumentException

Could not process multipart content

Error message

Could not process multipart content

What it means

setBinaryVariable reads the multipart request body via the servlet/parts API; an IOException while consuming that stream (broken upload, unreadable part, container I/O failure) is wrapped in this FlowableIllegalArgumentException. It signals the REST layer could not read or process the multipart content it received, before any variable is written.

Source

Thrown at modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/runtime/caze/BaseVariableResource.java:385

                setVariable(instanceId, variableName, value, scope, isNew, async, variableInterceptor);
                stream.close();
            } else {
                throw new FlowableContentNotSupportedException("Serialized objects are not allowed");
            }

            RestVariable restVariable = null;
            
            if (!async) {
                restVariable = getVariableFromRequestWithoutAccessCheck(instanceId, variableName, responseVariableType, false);
                
                // We are setting the scope because the fetched variable does not have it
                restVariable.setVariableScope(scope);
            }
            
            return restVariable;
            
        } catch (IOException ioe) {
            throw new FlowableIllegalArgumentException("Could not process multipart content", ioe);
            
        } catch (ClassNotFoundException ioe) {
            throw new FlowableContentNotSupportedException(
                    "The provided body contains a serialized object for which the class was not found: " + ioe.getMessage());
        }
    }

    protected void setVariable(String instanceId, String name, Object value, RestVariableScope scope, boolean isNew, boolean async, VariableInterceptor variableInterceptor) {
        if (isNew) {
            variableInterceptor.createVariables(Collections.singletonMap(name, value));
        } else {
            variableInterceptor.updateVariables(Collections.singletonMap(name, value));
        }

        if (RestVariableScope.LOCAL == scope) {
            //the guard is only added here, because this whole block is new
            if (isNew && runtimeService.hasLocalVariable(instanceId, name)) {
                throw new FlowableConflictException("Local variable '" + name + "' is already present on plan item instance '" + instanceId + "'.");

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Retry the upload, ensuring the request completes fully without interruption
  2. Check the servlet container temp directory (disk space, permissions) for multipart storage
  3. Increase client/server timeouts and any max-size limits for the upload
  4. Inspect the wrapped IOException cause for the root I/O problem (connection reset, disk error, etc.)

Example fix

// before
File diff suppressed: request sent with Content-Length mismatch / truncated body
// after
// verify content-length and stream the file fully; catch FlowableIllegalArgumentException
try {
    restClient.post().uri(variablesUrl).body(multipartData).retrieve().toBodilessEntity();
} catch (FlowableIllegalArgumentException e) {
    log.error("multipart upload failed: {}", e.getCause(), e);
}
Defensive patterns

Strategy: try-catch

Validate before calling

long contentLength = part.getSize();
if (contentLength <= 0) throw new IllegalStateException("Empty multipart part; check upload completed");

Type guard

null

Try / catch

try {
    postBinaryVariable(name, file);
} catch (HttpServerErrorException e) {
    if (e.getResponseBodyAsString().contains("Could not process multipart content")) {
        retryWithBackoff(() -> postBinaryVariable(name, file));
    }
}

Prevention

When it happens

Trigger: POST/PUT of a binary variable where the multipart stream is truncated or unreadable, the part cannot be accessed (e.g. temp file deleted), or an IOException is thrown by file.getInputStream()/readObject while reading the uploaded part.

Common situations: Network interruptions during large uploads, servlet container temp-directory issues (disk full, cleanup daemon deleting parts), proxy/gateway truncating request bodies, timeouts on slow uploads.

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/91b7097c9b8287dd. Report an issue: GitHub.