apache/iceberg · error · AlreadyExistsException
Database %s already exists in the iceberg catalog %s.
Error message
Database %s already exists in the iceberg catalog %s.
What it means
When creating a dynamic table source/sink, FlinkDynamicTableFactory auto-creates the database in the Iceberg catalog with ignoreIfExists=true; if createDatabase still reports DatabaseAlreadyExistException, it is rethrown as AlreadyExistsException with this message — indicating a race or inconsistent existence check.
Source
Thrown at flink/v2.2/flink/src/main/java/org/apache/iceberg/flink/FlinkDynamicTableFactory.java:213
String catalogDatabase = flinkConf.get(FlinkCreateTableOptions.CATALOG_DATABASE, databaseName);
Preconditions.checkArgument(
catalogDatabase != null,
"Invalid database name: null. Set %s create table option or specify fully qualified table name.",
FlinkCreateTableOptions.CATALOG_DATABASE);
String catalogTable = flinkConf.get(FlinkCreateTableOptions.CATALOG_TABLE, tableName);
FlinkCatalog flinkCatalog = createCatalogLoader(mergedProps, catalogName);
ObjectPath objectPath = new ObjectPath(catalogDatabase, catalogTable);
// Create database if not exists in the external catalog.
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);View on GitHub (pinned to 86d9c8fc54)
Solutions
- Retry the operation; the database now exists and the second attempt will succeed
- Serialize database/table bootstrap steps in deployment (one job creates schema first)
- Treat AlreadyExistsException as benign and proceed with loading the table loader
Example fix
// before
flinkCatalog.createDatabase(catalogDatabase, new CatalogDatabaseImpl(Maps.newHashMap(), null), true);
// after
try {
flinkCatalog.createDatabase(catalogDatabase, new CatalogDatabaseImpl(Maps.newHashMap(), null), true);
} catch (AlreadyExistsException e) {
// concurrent creation; database exists, continue
} Defensive patterns
Strategy: retry
Validate before calling
if (catalog.databaseExists(dbName)) { /* skip creation */ } Try / catch
try { loader.open(); } catch (AlreadyExistsException e) { /* concurrent creation; retry or proceed */ } Prevention
- Create databases/schemas before launching parallel Flink jobs
- Use ignoreIfExists semantics and treat duplicates as benign
When it happens
Trigger: createTableLoader runs, databaseExists returns false, then createDatabase races with another job/connection that creates the same database concurrently.
Common situations: Multiple Flink jobs starting simultaneously against the same Iceberg catalog, creating the same database namespace concurrently.
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.
- Table %s already exists in the database %s and 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/60862fd14cc2b061.
Report an issue: GitHub.