apache/seatunnel · error · UnknownPhysicalPlanException
The physical plan didn't have any can execute pipeline
Error message
The physical plan didn't have any can execute pipeline
What it means
PhysicalPlan's constructor validates that the submitted physical plan contains at least one executable pipeline; an empty pipelineList throws UnknownPhysicalPlanException with the message that the plan has no executable pipeline. A plan with zero pipelines cannot be scheduled, so the engine rejects it at construction time.
Source
Thrown at seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/dag/physical/PhysicalPlan.java:123
stateTimestamps[JobStatus.INITIALIZING.ordinal()] = initializationTimestamp;
runningJobStateTimestampsIMap.put(jobId, stateTimestamps);
}
if (runningJobStateIMap.get(jobId) == null) {
// We must update runningJobStateTimestampsIMap first and then can update
// runningJobStateIMap.
// Because if a new Master Node become active, we can recover ExecutionState and
// PipelineState and JobStatus
// from TaskExecutionService. But we can not recover stateTimestamps.
stateTimestamps[JobStatus.CREATED.ordinal()] = System.currentTimeMillis();
runningJobStateTimestampsIMap.put(jobId, stateTimestamps);
runningJobStateIMap.put(jobId, JobStatus.CREATED);
}
this.pipelineList = pipelineList;
if (pipelineList.isEmpty()) {
throw new UnknownPhysicalPlanException(
"The physical plan didn't have any can execute pipeline");
}
this.jobFullName =
String.format(
"Job %s (%s)",
jobImmutableInformation.getJobConfig().getName(),
jobImmutableInformation.getJobId());
this.runningJobStateIMap = runningJobStateIMap;
this.runningJobStateTimestampsIMap = runningJobStateTimestampsIMap;
}
public void setJobMaster(JobMaster jobMaster) {
this.jobMaster = jobMaster;
pipelineList.forEach(pipeline -> pipeline.setJobMaster(jobMaster));
this.engineConfig = jobMaster.getEngineConfig();
}
View on GitHub (pinned to cf67b549a7)
Solutions
- Review the job config: ensure it contains at least a source and a sink so the DAG yields a pipeline
- Run the config through the config validator / dry-run (e.g., seatunnel.sh --check) before submission
- Check whether plugin discovery failed so source/sink factories were missing and the planner pruned the DAG — look for earlier warnings in the logs
- If building plans programmatically, assert the logical plan's pipeline list is non-empty before constructing PhysicalPlan
- Verify the connector plugins are installed in the correct connectors directory for your version
Example fix
// before
// config.hocon with only a transform, no source/sink
env { parallelism = 1 }
transform { Sql { source_table_name = "x" } }
// after
env { parallelism = 1 }
source { FakeSource { result_table_name = "x" } }
transform { Sql { source_table_name = "x" } }
sink { Console { source_table_name = "x" } } Defensive patterns
Strategy: validation
Validate before calling
// before submission
if (logicalPlan == null || logicalPlan.getPipelines().isEmpty()) {
throw new IllegalArgumentException("Job config produced no pipelines; check source/sink config");
} Type guard
boolean hasPipelines(LogicalPlan p) { return p != null && !p.getPipelines().isEmpty(); } Try / catch
try {
submit(jobConfig);
} catch (UnknownPhysicalPlanException e) {
LOG.error("Job produced no pipelines — verify source and sink are configured and plugins installed", e);
} Prevention
- Always include a source and sink in job configs
- Run config validation / --check before submission
- Confirm connector plugins are installed for the engine version
When it happens
Trigger: Creating a PhysicalPlan from a logical plan that produced no pipelines — e.g., a job config whose DAG has no source/sink after optimization, all pipelines excluded by filters, or a malformed/empty job configuration.
Common situations: Job config with only a transform and no source/sink; a config error causing the DAG builder to drop all edges/nodes; programmatically built logical plans with empty pipeline lists; version-dependent planner changes that eliminate pipelines.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
- ${CONNECTOR_JAR_HA_STORAGE_TYPE} must in [localfile, hdfs]
- No actions define in the job. Cannot execute.
- The Jar package file for the connector is empty!
- Source And Sink can not be null
- intervalMs must be positive, got: %s
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/3016192476aea2d6.
Report an issue: GitHub.