apache/seatunnel · error · SeaTunnelRuntimeException
API-09
API-09
Error message
Handle save mode failed
What it means
SeaTunnelRuntimeException with code API-09 thrown by AbstractSinkExecuteProcessor.handleSaveMode when a sink's SaveModeHandler fails during open() or execution of its save-mode actions (table creation / schema evolution). The sink pipeline is aborted because pre-write DDL could not be applied.
Source
Thrown at seatunnel-core/seatunnel-flink-starter/seatunnel-flink-starter-common/src/main/java/org/apache/seatunnel/core/starter/flink/execution/AbstractSinkExecuteProcessor.java:262
}
if (sinks.values().stream().anyMatch(sink -> !(sink instanceof SupportMultiTableSink))) {
LOGGER.info("Unsupported multi table sink api, rollback to sink template");
// choose the first sink
return sinks.values().iterator().next();
}
return FactoryUtil.createMultiTableSink(sinks, sinkConfig, classLoader);
}
public void handleSaveMode(SeaTunnelSink seaTunnelSink) {
if (seaTunnelSink instanceof SupportSaveMode) {
SupportSaveMode saveModeSink = (SupportSaveMode) seaTunnelSink;
Optional<SaveModeHandler> saveModeHandler = saveModeSink.getSaveModeHandler();
if (saveModeHandler.isPresent()) {
try (SaveModeHandler handler = saveModeHandler.get()) {
handler.open();
new SaveModeExecuteWrapper(handler).execute();
} catch (Exception e) {
throw new SeaTunnelRuntimeException(HANDLE_SAVE_MODE_FAILED, e);
}
}
}
}
protected boolean shouldContinueOtherTables() {
return MultiTableFailureHelper.shouldContinueOtherTables(
ReadonlyConfig.fromConfig(envConfig));
}
protected RuntimeException wrapThrowable(Throwable error) {
if (error instanceof RuntimeException) {
return (RuntimeException) error;
}
return new RuntimeException(error);
}
private void logSkippedTable(View on GitHub (pinned to cf67b549a7)
Solutions
- Check the cause exception for the underlying database error
- Grant needed DDL privileges or pre-create tables and drop save_mode auto-creation
- Correct save_mode configuration (wrong SQL, wrong dialect) in the sink config
Defensive patterns
Strategy: try-catch
Validate before calling
// test save-mode DDL against target DB before job run
try (Statement s = conn.createStatement()) {
s.execute("SELECT 1"); // connection check
} Try / catch
try {
processor.execute();
} catch (SeaTunnelRuntimeException e) {
if ("API-09".equals(e.getSeaTunnelErrorCode().getCode())) {
log.error("Save mode handler failed: {}", e.getCause().getMessage());
}
throw e;
} Prevention
- Grant DDL privileges to the sink user
- Validate custom save_mode SQL for the target dialect
- Monitor catalog connectivity before job submission
When it happens
Trigger: Sink implements SupportsSaveMode and returns a SaveModeHandler; opening the catalog connection or executing the save-mode commands throws (privileges missing, invalid DDL, database unreachable) while handleSaveMode runs during execute().
Common situations: No CREATE privilege on the target database; custom save_mode SQL invalid for the dialect; transient catalog connectivity failures.
Related errors
- API-09
- SQL_OPERATION_FAILED
- TABLE_QUERY_FAILED
- CONFIG_VALIDATION_FAILED
- All candidate sink tables were skipped in Spark starter.
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/5d54394c22f9874f.
Report an issue: GitHub.