apache/seatunnel · error · SeaTunnelEngineException
The state must be end state from ExecutionService, can not b
Error message
The state must be end state from ExecutionService, can not be ${executionState} What it means
updateStateByExecutionService is the callback for ExecutionService task-completion notifications, which are only expected to deliver end states (FINISHED, FAILED, CANCELED). Receiving a non-end state means the internal contract between ExecutionService and PhysicalVertex is broken, so a SeaTunnelEngineException is thrown immediately.
Source
Thrown at seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/dag/physical/PhysicalVertex.java:535
"Set %s state %s to Imap failed, skip.",
getTaskFullName(), ExecutionState.CREATED));
}
this.currExecutionState = ExecutionState.CREATED;
log.info(String.format("%s turn to state %s.", taskFullName, ExecutionState.CREATED));
}
}
public void reset() {
resetExecutionState();
}
public String getTaskFullName() {
return taskFullName;
}
public void updateStateByExecutionService(TaskExecutionState taskExecutionState) {
if (!taskExecutionState.getExecutionState().isEndState()) {
throw new SeaTunnelEngineException(
String.format(
"The state must be end state from ExecutionService, can not be %s",
taskExecutionState.getExecutionState()));
}
errorByPhysicalVertex.compareAndSet(null, taskExecutionState.getThrowableMsg());
updateTaskState(taskExecutionState.getExecutionState());
}
public synchronized void forceStop() {
ExecutionState executionState = getExecutionState();
if (executionState == null || executionState.isEndState()) {
return;
}
noticeTaskExecutionServiceCancel();
if (!taskFuture.isDone()) {
updateTaskState(ExecutionState.CANCELED);
}
}View on GitHub (pinned to cf67b549a7)
Solutions
- Verify all engine modules run the same SeaTunnel version (no mixed jars)
- Ensure ExecutionService only notifies the vertex of terminal task states
- Check for custom patches/modified ExecutionService code and revert to upstream
- Capture logs of the offending TaskExecutionState and report the engine bug
Example fix
// before
vertex.updateStateByExecutionService(new TaskExecutionState(loc, ExecutionState.RUNNING, null));
// after
if (state.getExecutionState().isEndState()) {
vertex.updateStateByExecutionService(state);
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!taskExecutionState.getExecutionState().isEndState()) { return; // do not forward to updateStateByExecutionService } Type guard
boolean isTerminalTaskState(TaskExecutionState s) { return s.getExecutionState().isEndState(); } Try / catch
try { vertex.updateStateByExecutionState(tes); } catch (SeaTunnelEngineException e) { if (e.getMessage().contains("must be end state from ExecutionService")) { log.error("contract violation in task notification", e); } else { throw e; } } Prevention
- Only route terminal task states to the vertex
- Avoid mixed-version engine jars
- Test custom ExecutionService changes against the vertex contract
When it happens
Trigger: ExecutionService invokes updateStateByExecutionService with a TaskExecutionState whose execution state is RUNNING, CREATED, FAILING, etc.; an engine bug or version mismatch delivering intermediate states through this channel.
Common situations: Custom engine modifications that forward intermediate task states to the plan; mixed engine jar versions after an upgrade; bugs in task lifecycle reporting during failover.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- ${taskFullName} reset state failed, only end state can be re
- Job is trying to leave terminal state ${current}
- Unknown Job State: ${jobStatus}
- Unknown TaskGroup State: ${executionState}
- ${pipelineFullName} reset state failed, only end state can b
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/6b27c889ed2c894c.
Report an issue: GitHub.