flowable/flowable-engine · error · FlowableIllegalArgumentException
File must be of type .event, .channel
Error message
File must be of type .event, .channel
What it means
Flowable's event-registry REST deployment endpoint only accepts files ending in .event or .channel. Any other file extension is rejected with FlowableIllegalArgumentException during deployment upload. This guards the registry from storing resources it cannot interpret.
Solutions
- Rename the uploaded file so it ends with .event or .channel (lowercase).
- Ensure the export/download pipeline preserves the original extension (no suffixes appended).
- Check the multipart filename sent by the client, since the check uses the submitted file name not the content.
- If the resource is genuinely not an event/channel definition, use the appropriate deployment endpoint (e.g. process/DMN) instead.
Example fix
// before curl -F "file=@event-model.json" .../repository/deployments // after curl -F "file=@event-model.event" .../repository/deployments
Defensive patterns
Strategy: validation
Validate before calling
if (!fileName.endsWith(".event") && !fileName.endsWith(".channel")) {
throw new IllegalArgumentException("Rename file to .event or .channel before upload: " + fileName);
} Type guard
boolean isDeployable(String name) {
return name != null && (name.endsWith(".event") || name.endsWith(".channel"));
} Try / catch
try {
uploadDeployment(file);
} catch (FlowableIllegalArgumentException e) {
logger.error("Unsupported file type for event registry deployment", e);
} Prevention
- Keep original extensions through export/pipeline steps
- Check filename extension client-side before upload
- Avoid appending suffixes (timestamps, env) to uploaded filenames
When it happens
Trigger: POSTing a multipart file to the deployment collection endpoint whose filename lacks the .event or .channel extension (e.g. .xml, .json, .event.bak).
Common situations: Uploading generic model JSON instead of the exported event/channel file; renaming files before upload; using uppercase extensions like .EVENT; script wrappers that append timestamps to filenames.
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
- A channel key detection value is required for the channel…
- A group or a user is required to create an identity link.
- A group or a user is required to create an identity link.
- A group or a user is required to create an identity link.
- A request body was expected when bulk updating tasks.
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/99cfb26131addeda.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-event-registry-rest/src/main/java/org/flowable/eventregistry/rest/service/api/repository/DeploymentCollectionResource.java:199
throw new FlowableIllegalArgumentException("Multipart request with file content is required");
}
MultipartFile file = multipartRequest.getFileMap().values().iterator().next();
try {
EventDeploymentBuilder deploymentBuilder = repositoryService.createDeployment();
String fileName = file.getOriginalFilename();
if (StringUtils.isEmpty(fileName) || !(fileName.endsWith(".event") || fileName.endsWith(".channel"))) {
fileName = file.getName();
}
if (fileName.endsWith(".event") || fileName.endsWith(".channel")) {
try (final InputStream fileInputStream = file.getInputStream()) {
deploymentBuilder.addInputStream(fileName, fileInputStream);
}
} else {
throw new FlowableIllegalArgumentException("File must be of type .event, .channel");
}
if (!decodedQueryStrings.containsKey("deploymentName") || StringUtils.isEmpty(decodedQueryStrings.get("deploymentName"))) {
String fileNameWithoutExtension = fileName.split("\\.")[0];
if (StringUtils.isNotEmpty(fileNameWithoutExtension)) {
fileName = fileNameWithoutExtension;
}
deploymentBuilder.name(fileName);
} else {
deploymentBuilder.name(decodedQueryStrings.get("deploymentName"));
}
if (decodedQueryStrings.containsKey("category") || StringUtils.isNotEmpty(decodedQueryStrings.get("category"))) {
deploymentBuilder.category(decodedQueryStrings.get("category"));
}View on GitHub (pinned to d6d39ce1c6)