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

  1. Check the cause exception for the underlying database error
  2. Grant needed DDL privileges or pre-create tables and drop save_mode auto-creation
  3. 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

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


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/5d54394c22f9874f. Report an issue: GitHub.