apache/seatunnel · error · IllegalArgumentException
oracle_insert_mode=APPEND_VALUES only supports Oracle JDBC s
Error message
oracle_insert_mode=APPEND_VALUES only supports Oracle JDBC sink.
What it means
Thrown by JdbcOutputFormatBuilder.validateOracleInsertMode when oracle_insert_mode=APPEND_VALUES is configured but the active JDBC dialect is not Oracle. The APPEND_VALUES hint is Oracle-specific syntax and is meaningless (and invalid) on other databases, so the builder rejects the combination early.
Source
Thrown at seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/JdbcOutputFormatBuilder.java:380
}
final String insertPrefix = "INSERT";
if (!insertSQL.regionMatches(true, 0, insertPrefix, 0, insertPrefix.length())) {
throw new IllegalArgumentException(
"oracle_insert_mode=APPEND_VALUES only supports generated INSERT statements.");
}
String appendValuesSQL =
insertPrefix + " /*+ APPEND_VALUES */" + insertSQL.substring(insertPrefix.length());
log.info("Oracle APPEND_VALUES insert mode is enabled, generated SQL: {}", appendValuesSQL);
return appendValuesSQL;
}
private static void validateOracleInsertMode(
JdbcDialect dialect, JdbcSinkConfig jdbcSinkConfig, List<String> primaryKeys) {
if (!isOracleAppendValuesConfigured(jdbcSinkConfig)) {
return;
}
if (!DatabaseIdentifier.ORACLE.equals(dialect.dialectName())) {
throw new IllegalArgumentException(
"oracle_insert_mode=APPEND_VALUES only supports Oracle JDBC sink.");
}
if (primaryKeys != null && !primaryKeys.isEmpty()) {
throw new IllegalArgumentException(
"oracle_insert_mode=APPEND_VALUES only supports insert-only writes without primary keys.");
}
}
private static boolean isOracleAppendValuesConfigured(JdbcSinkConfig jdbcSinkConfig) {
return JdbcSinkConfig.OracleInsertMode.APPEND_VALUES.equals(
jdbcSinkConfig.getOracleInsertMode());
}
static Function<SeaTunnelRow, SeaTunnelRow> createKeyExtractor(int[] pkFields) {
return row -> {
Object[] fields = new Object[pkFields.length];
for (int i = 0; i < pkFields.length; i++) {
fields[i] = row.getField(pkFields[i]);View on GitHub (pinned to cf67b549a7)
Solutions
- Remove the oracle_insert_mode option if the target is not Oracle
- Switch the dialect/driver back to Oracle if Oracle was intended
- Use the dialect's own bulk-load/optimization options for the non-Oracle database
Example fix
// before url = "jdbc:mysql://host/db" oracle_insert_mode = "APPEND_VALUES" // after url = "jdbc:mysql://host/db"
Defensive patterns
Strategy: validation
Validate before calling
// ensure option matches dialect
if (config.get("oracle_insert_mode") != null && !dialectName.equals("oracle")) {
throw new IllegalArgumentException("oracle_insert_mode is Oracle-only");
} Try / catch
try { builder.build(); } catch (IllegalArgumentException e) {
if (e.getMessage().contains("only supports Oracle")) { /* remove option and rebuild */ }
} Prevention
- Keep Oracle-specific options in Oracle-only config profiles
- Verify dialect/driver pairs before submitting jobs
- Lint configs per dialect
When it happens
Trigger: Config contains oracle_insert_mode=APPEND_VALUES while dialect/dialectName() is not ORACLE — e.g. driver set to MySQL, PostgreSQL, etc.
Common situations: Copying an Oracle sink config template to another database; generic driver selection where the Oracle-only option was left enabled.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- oracle_insert_mode=APPEND_VALUES only supports generated INS
- oracle_insert_mode=APPEND_VALUES only supports insert-only w
- Failed to read schema for table %s
- No result returned after running query [%s]
- Failed to build the split data read statement.
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/53bbf634b47cf89b.
Report an issue: GitHub.