flowable/flowable-engine · error · FlowableIllegalArgumentException
Multipart request is required
Error message
Multipart request is required
What it means
FlowableIllegalArgumentException thrown by uploadDeployment when the HttpServletRequest is not a MultipartHttpServletRequest, i.e. the POST to /repository/deployments did not carry multipart/form-data content. The deployment upload API only accepts multipart requests containing the deployment file.
Source
Thrown at modules/flowable-rest/src/main/java/org/flowable/rest/service/api/repository/DeploymentCollectionResource.java:170
+ "An additional parameter (form-field) can be passed in the request body with name tenantId. The value of this field will be used as the id of the tenant this deployment is done in.",
code = 201)
@ApiResponses(value = {
@ApiResponse(code = 201, message = "Indicates the deployment was created."),
@ApiResponse(code = 400, message = "Indicates there was no content present in the request body or the content mime-type is not supported for deployment. The status-description contains additional information.")
})
@ApiImplicitParams({
@ApiImplicitParam(name = "file", dataType = "file", paramType = "form", required = true)
})
@PostMapping(value = "/repository/deployments", produces = "application/json", consumes = "multipart/form-data")
@ResponseStatus(HttpStatus.CREATED)
public DeploymentResponse uploadDeployment(@ApiParam(name = "deploymentKey") @RequestParam(value = "deploymentKey", required = false) String deploymentKey,
@ApiParam(name = "deploymentName") @RequestParam(value = "deploymentName", required = false) String deploymentName,
@ApiParam(name = "tenantId") @RequestParam(value = "tenantId", required = false) String tenantId,
HttpServletRequest request) {
if (!(request instanceof MultipartHttpServletRequest)) {
throw new FlowableIllegalArgumentException("Multipart request is required");
}
if (restApiInterceptor != null) {
restApiInterceptor.executeNewDeploymentForTenantId(tenantId);
}
String queryString = request.getQueryString();
Map<String, String> decodedQueryStrings = splitQueryString(queryString);
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
if (multipartRequest.getFileMap().size() == 0) {
throw new FlowableIllegalArgumentException("Multipart request with file content is required");
}
MultipartFile file = multipartRequest.getFileMap().values().iterator().next();
try {View on GitHub (pinned to d6d39ce1c6)
Solutions
- Send the request as multipart/form-data, e.g. curl -F "file=@process.bpmn20.xml" ...
- Set the correct Content-Type header (let the HTTP client set the multipart boundary automatically)
- Attach the deployment file as a file part, not as a form field or raw body
- Verify the multipart resolver (MultipartResolver / spring.servlet.multipart.enabled=true) is configured server-side
Example fix
// before
curl -u admin:test -X POST -H 'Content-Type: application/json' \
-d '{"name":"myDeployment"}' http://localhost:8080/flowable-rest/repository/deployments
// after
curl -u admin:test -X POST -F "deploymentName=myDeployment" \
-F "file=@process.bpmn20.xml" http://localhost:8080/flowable-rest/repository/deployments Defensive patterns
Strategy: validation
Validate before calling
// client-side check before sending
if (!headers['Content-Type'].startsWith('multipart/form-data')) throw new Error('Deployment upload must be multipart/form-data'); Try / catch
try {
rest.postForDeployment(file)
} catch (HttpClientErrorException.BadRequest e) {
if (e.body.message?.contains('Multipart request is required')) {
throw new Error('Fix request: use multipart/form-data with a file part, e.g. curl -F file=@process.bpmn20.xml')
}
} Prevention
- Always upload deployments with curl -F / FormData, never -d or JSON bodies
- Let the HTTP client generate the multipart boundary and Content-Type automatically
- Verify server-side multipart resolver is enabled in Spring configuration
When it happens
Trigger: POST /repository/deployments with Content-Type application/json, application/x-www-form-urlencoded, or omitted Content-Type entirely instead of multipart/form-data with a file part.
Common situations: curl calls using -d instead of -F, clients sending the bpmn XML as a raw body or JSON field, missing multipart resolver in Spring config so the request is never wrapped, proxies stripping the Content-Type.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Multipart request is required
- Multipart request with file content is required
- No file content was found in request body.
- Multipart request with file content is required
- Multipart request is required
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/708042a7398cacd1.
Report an issue: GitHub.