apache/seatunnel · error · SeaTunnelRuntimeException
HANDLE_SAVE_MODE_FAILED
HANDLE_SAVE_MODE_FAILED
Error message
All candidate sink tables were skipped during cluster save mode.
What it means
During cluster save-mode handling, JobMaster.handleSaveMode applies each sink table's save-mode (e.g. drop/create) and collects tables that failed. Failed tables are removed from the MultiTableSink and registered as initial failures; if that leaves zero sinks, nothing can be written, so a SeaTunnelRuntimeException with code HANDLE_SAVE_MODE_FAILED is thrown containing a formatted summary of all failed tables.
Source
Thrown at seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/master/JobMaster.java:832
entry.getValue().getPluginName(),
error);
failedTables.add(failedTable);
LOGGER.warning(
"Skip failed sink table during cluster save mode: "
+ MultiTableFailureHelper.formatFailedTableLine(failedTable),
error);
}
}
if (failedTables.isEmpty()) {
return;
}
failedTables.forEach(
failedTable ->
multiTableSink.removeSink(TablePath.of(failedTable.getTablePath())));
multiTableSink.registerInitialFailedTables(failedTables);
if (multiTableSink.getSinks().isEmpty()) {
throw new SeaTunnelRuntimeException(
HANDLE_SAVE_MODE_FAILED,
new IllegalStateException(
MultiTableFailureHelper.formatFailedTableSummary(
"All candidate sink tables were skipped during cluster save mode.",
failedTables)));
}
}
}
public void handleCheckpointError(long pipelineId, boolean neverRestore) {
if (neverRestore) {
this.neverNeedRestore();
}
this.physicalPlan
.getPipelineList()
.forEach(
pipeline -> {
if (pipeline.getPipelineLocation().getPipelineId() == pipelineId) {View on GitHub (pinned to cf67b549a7)
Solutions
- Inspect the formatted failed-table summary in the exception to see each table's root failure and fix the per-table cause (permissions, connection, table path).
- Grant the sink user the privileges required by the configured save mode (e.g. DROP/CREATE TABLE).
- Verify catalog configuration and table paths for the sink tables.
- Change the save mode (e.g. from DROP to CREATE_OR_REPLACE/ERROR) to one that can succeed for these tables.
Example fix
// before
sink {
Jdbc {
save_mode = "drop"
}
}
// after: use a less privileged save mode
sink {
Jdbc {
save_mode = "error"
}
} Defensive patterns
Strategy: validation
Validate before calling
// preflight: test save-mode privilege per sink table
for (TablePath t : sinkTables) {
if (!catalog.tableExists(t) && saveModeRequiresExisting(t)) {
fail("table missing and save mode cannot create it: " + t);
}
}
if (failedTables.size() == sinkTables.size()) fail("all sink tables will be skipped"); Try / catch
try {
submitJob(conf);
} catch (SeaTunnelRuntimeException e) {
if ("HANDLE_SAVE_MODE_FAILED".equals(e.getSeaTunnelErrorCode().getCode())) {
log.error("save-mode failed summary: {}", e.getMessage()); // inspect per-table causes
}
throw e;
} Prevention
- Grant the sink user the DDL privileges required by the configured save mode.
- Test save mode against a staging database before production runs.
- Validate catalog config and table paths for every sink table in the job.
When it happens
Trigger: Running a multi-table sink job in cluster save mode where EVERY candidate sink table's save-mode execution failed (e.g. DROP TABLE failed for all tables due to permissions or connection issues), leaving multiTableSink empty.
Common situations: Sink user lacking DROP/CREATE privileges on all target tables; database unreachable; wrong catalog/table paths configured for all tables; schema mismatches causing every table's save-mode step to be skipped.
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
- All candidate sink tables were skipped in Spark starter.
- MultiTableWriterRunnable can't find writer for tableId:
- Elasticsearch multi-table writer requires ElasticsearchMulti
- TABLE_QUERY_FAILED
- CONFIG_VALIDATION_FAILED
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/ea7e2299c2ebe492.
Report an issue: GitHub.