apache/seatunnel · error · TableAlreadyExistException

Table 'TablePath{databaseName='null', schemaName='null', tab

Error message

Table 'TablePath{databaseName='null', schemaName='null', tableName='null'}' already exists in catalog 'null'

What it means

Thrown by AbstractJdbcCatalog.createTable when the target table already exists and ignoreIfExists is false; the standard TableAlreadyExistException sentinel rendered with the (possibly null-field) TablePath and catalog name identifying the conflict.

Source

Thrown at seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/AbstractJdbcCatalog.java:484

            throws TableAlreadyExistException, DatabaseNotExistException, CatalogException {
        checkNotNull(tablePath, "Table path cannot be null");

        if (!databaseExists(tablePath.getDatabaseName())) {
            throw new DatabaseNotExistException(catalogName, tablePath.getDatabaseName());
        }
        if (defaultSchema.isPresent()) {
            tablePath =
                    new TablePath(
                            tablePath.getDatabaseName(),
                            defaultSchema.get(),
                            tablePath.getTableName());
        }

        if (tableExists(tablePath)) {
            if (ignoreIfExists) {
                return;
            }
            throw new TableAlreadyExistException(catalogName, tablePath);
        }

        createTableInternal(tablePath, table, createIndex);
    }

    protected String getCreateTableSql(
            TablePath tablePath, CatalogTable table, boolean createIndex) {
        throw new UnsupportedOperationException();
    }

    protected List<String> getCreateTableSqls(
            TablePath tablePath, CatalogTable table, boolean createIndex) {
        return Collections.singletonList(getCreateTableSql(tablePath, table, createIndex));
    }

    protected void createTableInternal(TablePath tablePath, CatalogTable table, boolean createIndex)
            throws CatalogException {
        String dbUrl = getUrlFromDatabaseName(tablePath.getDatabaseName());

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Pass ignoreIfExists=true (in the 4-arg overload) if re-running should be a no-op
  2. Drop the existing table first with catalog.dropTable(path, false) if replacement is intended
  3. Use a distinct table name or versioned table names for each run
  4. Catch TableAlreadyExistException and treat as success in idempotent pipelines

Example fix

// before
catalog.createTable(path, table, false); // fails on rerun
// after
catalog.createTable(path, table, true); // ignore if already exists
Defensive patterns

Strategy: try-catch

Validate before calling

boolean exists;
try {
    exists = catalog.tableExists(path);
} catch (Exception e) { exists = false; }
if (exists) { /* skip or drop first */ }

Try / catch

try {
    catalog.createTable(path, table, false);
} catch (TableAlreadyExistException e) {
    // idempotent rerun: treat as success
}

Prevention

When it happens

Trigger: Calling createTable(..., ignoreIfExists=false) for a table that already exists — e.g. re-running a non-idempotent schema-migration job.

Common situations: Idempotency issues: job reruns after partial failure; multiple pipelines creating the same table concurrently; developer forgot to set ignoreIfExists=true for upsert-style workflows.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


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