flowable/flowable-engine · error · FlowableException
No message start event found for process definition
Error message
No message start event found for process definition ${id} and message name ${messageName} What it means
Thrown when starting a process instance by message and no StartEvent in the resolved process model has a MessageEventDefinition whose message name matches the given messageName. The engine cannot determine which start event to use.
Solutions
- Match the messageName string exactly to the name of the <message> referenced by the start event in the BPMN XML.
- Add a <startEvent><messageEventDefinition messageRef="..."/></startEvent> plus the <message> declaration and redeploy.
- Check you resolved the right definition (key/tenantId) — pass tenantId if messages are tenant-scoped.
- Use RuntimeService.createProcessDefinitionQuery().processDefinitionKey(key) to inspect the active version and confirm it contains the message start event.
Example fix
// before
runtimeService.startProcessInstanceByMessage("orderRecieved", vars); // typo
// after
// <message id="orderReceivedMsg" name="orderReceived"/>
runtimeService.startProcessInstanceByMessage("orderReceived", vars); Defensive patterns
Strategy: validation
Validate before calling
BpmnModel model = repositoryService.getBpmnModel(def.getId());
boolean hasMsgStart = model.getMainProcess().getFlowElements().stream()
.filter(org.flowable.bpmn.model.StartEvent.class::isInstance)
.map(fe -> (org.flowable.bpmn.model.StartEvent) fe)
.flatMap(se -> se.getEventDefinitions().stream())
.anyMatch(ed -> ed instanceof org.flowable.bpmn.model.MessageEventDefinition
&& messageName.equals(((org.flowable.bpmn.model.MessageEventDefinition) ed).getMessageName()));
if (!hasMsgStart) throw new IllegalArgumentException("No message start event '" + messageName + "' on " + def.getId()); Type guard
public static boolean isMessageStartEvent(StartEvent se, String messageName) {
return se.getEventDefinitions().stream()
.filter(MessageEventDefinition.class::isInstance)
.map(MessageEventDefinition.class::cast)
.anyMatch(ed -> messageName.equals(ed.getMessageName()));
} Try / catch
try {
runtimeService.startProcessInstanceByMessage(messageName, vars);
} catch (FlowableException e) {
if (e.getMessage().startsWith("No message start event found")) {
throw new IllegalArgumentException("Message '" + messageName + "' has no start event in the active definition", e);
}
throw e;
} Prevention
- Centralize message names as constants shared between BPMN and producers
- Keep <message> declarations and messageRefs in sync when renaming
- Re-check message start events on every new process version
- Pass tenantId explicitly for tenant-scoped message resolution
When it happens
Trigger: RuntimeService.startProcessInstanceByMessage(messageName, ...) where messageName is not declared on any <messageStartEvent> of the process definition resolved (by key or tenant).
Common situations: Message name mismatch between the BPMN <message name="..."> and the caller; missing <message> declaration in the model; a new process version dropped the message start event; wrong tenant — another tenant's definition has the event but the resolved one does not.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- BPMN XSD could not be found
- Cannot create an event-throwing event-listener, unknown…
- Cannot create 'script' task listener. Missing ScriptInfo.
- Cannot create 'script' type execution listener. Missing…
- Cannot deploy process definition
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/08a327cccbfe3818.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/util/ProcessInstanceHelper.java:159
if (process == null) {
throw new FlowableException("Cannot start process instance. Process model " + processDefinition.getName() + " (id = " + processDefinition.getId() + ") could not be found");
}
FlowElement initialFlowElement = null;
for (FlowElement flowElement : process.getFlowElements()) {
if (flowElement instanceof StartEvent startEvent) {
if (CollectionUtil.isNotEmpty(startEvent.getEventDefinitions()) && startEvent.getEventDefinitions()
.get(0) instanceof MessageEventDefinition messageEventDefinition) {
String actualMessageName = EventDefinitionExpressionUtil.determineMessageName(commandContext, messageEventDefinition, processDefinition);
if (Objects.equals(actualMessageName, messageName)) {
initialFlowElement = flowElement;
break;
}
}
}
}
if (initialFlowElement == null) {
throw new FlowableException("No message start event found for process definition " + processDefinition.getId() + " and message name " + messageName);
}
return createAndStartProcessInstanceWithInitialFlowElement(processDefinition, businessKey, businessStatus, null, null, null, initialFlowElement,
process, variables, transientVariables, callbackId, callbackType, referenceId, referenceType, ownerId, assigneeId, null, true);
}
public ProcessInstance createAndStartProcessInstanceWithInitialFlowElement(ProcessDefinition processDefinition,
String businessKey, String businessStatus, String processInstanceName, FlowElement initialFlowElement, Process process,
Map<String, Object> variables,
Map<String, Object> transientVariables, String ownerId, String assigneeId, boolean startProcessInstance) {
return createAndStartProcessInstanceWithInitialFlowElement(processDefinition, businessKey, businessStatus, processInstanceName, null, null,
initialFlowElement, process, variables, transientVariables, null, null, null, null,
ownerId, assigneeId, null, startProcessInstance);
}
public ProcessInstance createAndStartProcessInstanceWithInitialFlowElement(ProcessDefinition processDefinition,
String businessKey, String businessStatus, String processInstanceName,View on GitHub (pinned to d6d39ce1c6)