apache/seatunnel · error · SeaTunnelRuntimeException
API-09
API-09
Error message
Handle save mode failed
What it means
Thrown when executing a sink's SaveModeHandler — the pre-write actions like auto-create-table, drop-table, or clear-data — fails. The handler is opened, executed via SaveModeExecuteWrapper, and any Exception is rethrown as a SeaTunnelRuntimeException with code API-09 ('Handle save mode failed'). The root cause (typically a database error) is attached.
Solutions
- Read the 'Caused by' exception to see the actual database/DDL error
- Grant the DB user the privileges needed by the save-mode (CREATE TABLE / DROP TABLE)
- Change the save-mode option (e.g. from create_when_not_exist/drop_and_create to error_if_schema_mismatch or reuse the existing table)
- Test the DDL manually against the target database
Example fix
// before save_mode = "DROP_AND_CREATE" // after save_mode = "APPEND" # or ERROR_IF_SCHEMA_MISMATCH if DDL privileges are missing
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-flight: check DDL privileges on the target database // GRANT CREATE, DROP ON target_db.* TO 'seatunnel_user'@'%';
Try / catch
try {
runJob();
} catch (SeaTunnelRuntimeException e) {
if ("API-09".equals(((SeaTunnelRuntimeException) e).getSeaTunnelErrorCode().getCode())) {
log.error("Save-mode DDL failed; check cause", e.getCause());
}
} Prevention
- Grant the sink DB user CREATE/DROP privileges required by the chosen save-mode
- Prefer conservative save modes (APPEND / error_if_schema_mismatch) in production
- Test save-mode DDL manually against the target DB before running jobs
When it happens
Trigger: Sink implements SupportSaveMode and its SaveModeHandler.open() or execute() throws — e.g. CREATE TABLE fails on the target database (insufficient privileges, syntax unsupported, connection failure), or DROP/TRUNCATE of an existing table fails.
Common situations: Target database user lacks CREATE/DROP privileges; table exists with a conflicting schema; JDBC dialect in the save-mode handler not supporting the target DB version; network/credentials issues to the catalog DB.
Related errors
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/1cfe3bf58add8205.
Report an issue: GitHub.
Appendix: source
Thrown at seatunnel-core/seatunnel-spark-starter/seatunnel-spark-starter-common/src/main/java/org/apache/seatunnel/core/starter/spark/execution/SinkExecuteProcessor.java:226
if (createdAnySink && !skippedTables.isEmpty()) {
log.warn(
MultiTableFailureHelper.formatFailedTableSummary(
"Some sink tables were skipped in Spark starter.", skippedTables));
}
// the sink is the last stream
return null;
}
public void handleSaveMode(SeaTunnelSink sink) {
if (sink instanceof SupportSaveMode) {
Optional<SaveModeHandler> saveModeHandler =
((SupportSaveMode) sink).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);
}
}
}
}
private boolean shouldContinueOtherTables() {
return MultiTableFailureHelper.shouldContinueOtherTables(
ReadonlyConfig.fromConfig(sparkRuntimeEnvironment.getConfig()));
}
private RuntimeException wrapThrowable(Throwable error) {
if (error instanceof RuntimeException) {
return (RuntimeException) error;
}
return new RuntimeException(error);
}
private void logSkippedTable(View on GitHub (pinned to cf67b549a7)