flowable/flowable-engine · error · FlowableIllegalArgumentException
Multipart request is required
Error message
Multipart request is required
What it means
POST /dmn-repository/deployments only accepts multipart/form-data. The handler checks whether the incoming HttpServletRequest is a Spring MultipartHttpServletRequest and throws FlowableIllegalArgumentException if not. This is a request-shape validation: the deployment API always requires uploaded file parts.
Source
Thrown at modules/flowable-dmn-rest/src/main/java/org/flowable/dmn/rest/service/api/repository/DmnDeploymentCollectionResource.java:159
@ApiOperation(value = "Create a new decision deployment", nickname = "uploadDecisionDeployment", tags = {
"Deployment" }, consumes = "multipart/form-data", produces = "application/json", notes = "The request body should contain data of type multipart/form-data. There should be exactly one file in the request, any additional files will be ignored. The deployment name is the name of the file-field passed in. If multiple resources need to be deployed in a single deployment, compress the resources in a zip and make sure the file-name ends with .bar or .zip.\n"
+ "\n"
+ "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", paramType = "form", dataType = "java.io.File")
})
@PostMapping(value = "/dmn-repository/deployments", produces = "application/json", consumes = "multipart/form-data")
@ResponseStatus(HttpStatus.CREATED)
public DmnDeploymentResponse uploadDeployment(@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);
}
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 {
DmnDeploymentBuilder deploymentBuilder = dmnRepositoryService.createDeployment();
String fileName = file.getOriginalFilename();
if (StringUtils.isEmpty(fileName) || !DmnResourceUtil.isDmnResource(fileName)) {View on GitHub (pinned to d6d39ce1c6)
Solutions
- Send the request as multipart/form-data with the .dmn file as a file part (curl -F 'file=@decision.dmn').
- Ensure the client library attaches files as form-data parts, not as a JSON body.
- Verify multipart support is enabled (spring.servlet.multipart.enabled=true in Spring Boot).
- Confirm no intermediary proxy rewrites the Content-Type or body.
Example fix
// before
curl -X POST -H 'Content-Type: application/json' -d '{"file":"decision.dmn"}' http://host/flowable-dmn/dmn-repository/deployments
// after
curl -X POST -F 'file=@decision.dmn' http://host/flowable-dmn/dmn-repository/deployments Defensive patterns
Strategy: validation
Validate before calling
const ct = request.headers['content-type'] || '';
if (!ct.includes('multipart/form-data')) throw new Error('must send multipart/form-data'); Try / catch
try { return await deploy(file); }
catch (e) { if (e.status === 400 && /Multipart request/.test(e.message)) { console.error('send multipart/form-data with a file part'); } throw e; } Prevention
- Use curl -F or a client that sends file parts for deployment uploads
- Never send JSON bodies to the deployments endpoint
- Enable servlet multipart support in Spring Boot
- Check Content-Type includes a boundary
When it happens
Trigger: Sending POST /dmn-repository/deployments with Content-Type application/json, application/x-www-form-urlencoded, or missing multipart parts, so Spring never wraps the request as multipart.
Common situations: REST clients forgetting to set 'Content-Type: multipart/form-data' (or the boundary), curl calls using -d instead of -F, proxies/gateways stripping the multipart wrapper, or the servlet multipart support not being enabled in Spring Boot config.
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
- No variable name was found in request body.
- Multipart request with file content is required
- No file content was found in request body.
- No variable name was found in request body.
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/a49330a317fb57ff.
Report an issue: GitHub.