flowable/flowable-engine · error · FlowableException
Cannot start process instance by message: subscription to…
Error message
Cannot start process instance by message: subscription to message with name '${messageName}' is not a message start event. What it means
Flowable throws this when a message event subscription exists for the given message name, but its configuration does not point to a process definition — i.e. the subscription is not a message start event of a top-level process. StartProcessInstanceByMessageCmd can only start a process instance from a message start event; intermediate message catches or other subscription types are rejected.
Solutions
- Declare the message on a message start event in the BPMN XML: <startEvent><messageEventDefinition messageRef="..."/></startEvent>
- Verify the messageName passed to startProcessInstanceByMessage exactly matches the message start event's message name
- Check that the latest deployment actually contains the message start event subscription
- If the message targets an intermediate/boundary event, use RuntimeService.messageEventReceived(...) or execution.trigger instead
Example fix
// before (BPMN): message only on intermediate catch catchEvent id="wait" messageRef="orderMsg" // after (BPMN): message on start event <startEvent id="start"><messageEventDefinition messageRef="orderMsg"/></startEvent>
Defensive patterns
Strategy: validation
Validate before calling
MessageEventSubscription sub = runtimeService.createEventSubscriptionQuery()
.messageEventSubscriptionName("orderMsg").singleResult();
if (sub == null || !runtimeService.createProcessDefinitionQuery()
.processDefinitionKey("orderProcess").count() > 0) {
throw new IllegalStateException("message start event not deployed for orderMsg");
} Type guard
boolean hasMessageStartEvent(RuntimeService rs, String msg) {
return rs.createEventSubscriptionQuery().messageEventSubscriptionName(msg).singleResult() != null;
} Try / catch
try {
runtimeService.startProcessInstanceByMessage("orderMsg");
} catch (FlowableException e) {
if (e.getMessage().contains("not a message start event")) { /* fix BPMN / use messageEventReceived */ }
throw e;
} Prevention
- Always declare process-start messages on a <startEvent><messageEventDefinition>
- Unit-test message start by attempting the start in an integration test after deployment
- Keep message names in constants shared between BPMN XML and Java code
When it happens
Trigger: Calling RuntimeService.startProcessInstanceByMessage(messageName, ...) when the subscription found for messageName belongs to a non-start event (e.g. an intermediate catch message event or boundary event), so messageEventSubscription.getConfiguration() returns null.
Common situations: The BPMN XML declares the message only on an intermediate catch or boundary event instead of a <startEvent><messageEventDefinition>; a typo makes the API match a wrong subscription type; the process was re-deployed and the start-event subscription was replaced.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Cannot complete BPMN job. There is no BPMN engine available
- Cannot create an event-throwing event-listener, unknown…
- Cannot deploy process definition
- Cannot deploy process definition
- Cannot query external jobs. There is no BPMN or CMMN engine…
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/26e60c8f1acd0431.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/StartProcessInstanceByMessageCmd.java:97
@Override
public ProcessInstance execute(CommandContext commandContext) {
if (messageName == null) {
throw new FlowableIllegalArgumentException("Cannot start process instance by message: message name is null");
}
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
MessageEventSubscriptionEntity messageEventSubscription = processEngineConfiguration.getEventSubscriptionServiceConfiguration().getEventSubscriptionService()
.findMessageStartEventSubscriptionByName(messageName, tenantId);
if (messageEventSubscription == null) {
throw new FlowableObjectNotFoundException("Cannot start process instance by message: no subscription to message with name '" + messageName + "' found.", MessageEventSubscriptionEntity.class);
}
String processDefinitionId = messageEventSubscription.getConfiguration();
if (processDefinitionId == null) {
throw new FlowableException("Cannot start process instance by message: subscription to message with name '" + messageName + "' is not a message start event.");
}
DeploymentManager deploymentCache = processEngineConfiguration.getDeploymentManager();
ProcessDefinition processDefinition = deploymentCache.findDeployedProcessDefinitionById(processDefinitionId);
if (processDefinition == null) {
throw new FlowableObjectNotFoundException("No process definition found for id '" + processDefinitionId + "'", ProcessDefinition.class);
}
ProcessInstanceHelper processInstanceHelper = processEngineConfiguration.getProcessInstanceHelper();
ProcessInstance processInstance = processInstanceHelper.createAndStartProcessInstanceByMessage(processDefinition,
messageName, businessKey, businessStatus, processVariables, transientVariables, callbackId, callbackType, referenceId, referenceType,
ownerId, assigneeId);
return processInstance;
}
}
View on GitHub (pinned to d6d39ce1c6)