apache/seatunnel · error · PaimonConnectorException
UNSUPPORTED_BRANCH_SAVE_MODE
UNSUPPORTED_BRANCH_SAVE_MODE
Error message
Paimon branch '${branch}' does not support this save mode for table '${tablePath}'. The main table must exist before writing to a non-main branch. What it means
When writing to a non-main Paimon branch, the main table must already exist; branch writes operate on an existing table's branch, not a fresh one. If the main table is absent, save-mode handling cannot proceed safely and throws UNSUPPORTED_BRANCH_SAVE_MODE.
Source
Thrown at seatunnel-connectors-v2/connector-paimon/src/main/java/org/apache/seatunnel/connectors/seatunnel/paimon/handler/PaimonSaveModeHandler.java:96
}
@Override
public void handleSchemaSaveModeWithRestore() {
checkBranchSaveMode();
super.handleSchemaSaveModeWithRestore();
}
private boolean isNonMainBranch() {
return StringUtils.isNotEmpty(branch)
&& !BranchManager.DEFAULT_MAIN_BRANCH.equalsIgnoreCase(branch);
}
private void checkBranchSaveMode() {
if (!isNonMainBranch()) {
return;
}
if (!catalog.tableExists(tablePath)) {
throw unsupportedBranchSaveMode(
"The main table must exist before writing to a non-main branch.");
}
Table paimonTable = ((PaimonCatalog) catalog).getPaimonTable(tablePath);
if (!((FileStoreTable) paimonTable).branchManager().branchExists(branch)) {
throw new PaimonConnectorException(
PaimonConnectorErrorCode.BRANCH_NOT_EXISTS,
String.format(
"Specified branch '%s' of table '%s' does not exist.",
branch, tablePath));
}
if (this.schemaSaveMode == SchemaSaveMode.RECREATE_SCHEMA) {
throw unsupportedBranchSaveMode(
"schema_save_mode=RECREATE_SCHEMA would drop and recreate the main table.");
}
if (this.dataSaveMode == DataSaveMode.DROP_DATA) {
throw unsupportedBranchSaveMode(
"data_save_mode=DROP_DATA would truncate the main table.");
}View on GitHub (pinned to cf67b549a7)
Solutions
- Create the main table first (e.g. via catalog/CREATE TABLE or a prior job writing to the main branch), then write to the branch
- Remove the branch option or set it to 'main' for the initial table creation run
- Verify the table path spelling matches an existing table
Example fix
// before: first run directly on a branch
sink { Paimon { branch = "audit", schema_save_mode = CREATE_SCHEMA_WHEN_NOT_EXIST } }
// after: create main table first, then branch write
sink { Paimon { schema_save_mode = CREATE_SCHEMA_WHEN_NOT_EXIST } } // run once on main
sink { Paimon { branch = "audit" } } // then write to branch Defensive patterns
Strategy: validation
Validate before calling
// before running a branch write, ensure the main table exists
// via Paimon catalog:
if (!catalog.tableExists(TablePath.of("db.db.tbl"))) {
catalog.createTable(TablePath.of("db.db.tbl"), schema, partitions, props);
} Try / catch
try {
handleSaveMode();
} catch (PaimonConnectorException e) {
if (e.getErrorCode() == UNSUPPORTED_BRANCH_SAVE_MODE && e.getMessage().contains("must exist")) {
createMainTableThenRetry();
} else throw e;
} Prevention
- Always create the main table before configuring branch writes
- Verify table paths against the catalog before job submission
- Avoid implicit table creation when using branches
When it happens
Trigger: sink with branch configured to a non-main branch while schema_save_mode/data_save_mode handling runs and catalog.tableExists(tablePath) is false — i.e. first-time write where the main table was never created.
Common situations: Creating the table implicitly via a sink write to a branch; dropped main table but branch config still set; typo in table path so existence check fails.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- BRANCH_NOT_EXISTS
- BRANCH_NOT_EXISTS
- TABLE_QUERY_FAILED
- BRANCH_NOT_EXISTS
- Cross Partitions Upsert Dynamic Bucket Mode is not supported
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/f50a8441703416c6.
Report an issue: GitHub.