apache/iceberg · error · org.apache.flink.table.api.AlreadyExistsException
Table %s already exists in the database %s and catalog %s
Error message
Table %s already exists in the database %s and catalog %s
What it means
FlinkDynamicTableFactory attempts to create the Iceberg table in the external catalog if tableExists says it is absent; if createIcebergTable then throws TableAlreadyExistException (the table appeared concurrently or the check was stale), it rethrows as AlreadyExistsException. It reports that the requested table already exists in the given database and catalog.
Source
Thrown at flink/v2.1/flink/src/main/java/org/apache/iceberg/flink/FlinkDynamicTableFactory.java:226
if (!flinkCatalog.databaseExists(catalogDatabase)) {
try {
flinkCatalog.createDatabase(
catalogDatabase, new CatalogDatabaseImpl(Maps.newHashMap(), null), true);
} catch (DatabaseAlreadyExistException e) {
throw new AlreadyExistsException(
e,
"Database %s already exists in the iceberg catalog %s.",
catalogName,
catalogDatabase);
}
}
// Create table if not exists in the external catalog.
if (!flinkCatalog.tableExists(objectPath)) {
try {
flinkCatalog.createIcebergTable(objectPath, resolvedCatalogTable, true);
} catch (TableAlreadyExistException e) {
throw new AlreadyExistsException(
e,
"Table %s already exists in the database %s and catalog %s",
catalogTable,
catalogDatabase,
catalogName);
}
}
return TableLoader.fromCatalog(
flinkCatalog.getCatalogLoader(), TableIdentifier.of(catalogDatabase, catalogTable));
}
/**
* Merges source catalog properties (catalog name, database, table) with connector properties.
* Source catalog name, database, table are serialized as json in FlinkCatalog#getTable to be able
* to isolate them from iceberg table props, Here, we flatten and merge them back.
*
* @param tableProps the existing table propertiesView on GitHub (pinned to 86d9c8fc54)
Solutions
- Verify the existing table's schema matches what you intended; if so, just use it — retry the query.
- Drop or rename the existing table if it was created with the wrong schema (DROP TABLE ... then resubmit).
- Gate table creation in your deployment pipeline (create once, then start jobs) to avoid the race.
Example fix
// before CREATE TABLE catalog.db.events (...); // two jobs racing // after // job A: create table once; job B just reads/writes CREATE TABLE IF NOT EXISTS catalog.db.events (...);
Defensive patterns
Strategy: try-catch
Validate before calling
if (flinkCatalog.tableExists(objectPath)) { /* skip creation; verify schema instead */ } Try / catch
try {
flinkCatalog.createIcebergTable(objectPath, table, true);
} catch (TableAlreadyExistException e) {
// table exists: compare schemas and proceed if compatible
} Prevention
- Create tables once in a controlled pipeline step, not inside every job's startup.
- Use CREATE TABLE IF NOT EXISTS semantics or ignoreIfExists-style flags.
- On retry loops, check tableExists before re-submitting creation.
When it happens
Trigger: createTableLoader (via createDynamicTableSource/createDynamicTableSink) when tableExists(objectPath) is false but flinkCatalog.createIcebergTable(objectPath, resolvedCatalogTable, true) throws TableAlreadyExistException.
Common situations: Two Flink jobs submitting the same new table concurrently; schema-evolution statements resubmitted in a retry loop; a sink and a source job both creating the table on startup.
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
- Database %s already exists in the iceberg catalog %s.
- Database %s already exists in the iceberg catalog %s.
- Table %s already exists in the database %s and catalog %s
- Database %s already exists in the iceberg catalog %s.
- Table %s already exists in the database %s and catalog %s
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/ae18ae7dc00a97c0.
Report an issue: GitHub.