apache/iceberg · error · org.apache.flink.table.api.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 FlinkDynamicTableFactory creates a table loader and the target Iceberg database does not exist, it tries to create it with ignoreIfExists=false semantics via createDatabase; if the database was created concurrently (DatabaseAlreadyExistException), it rethrows as AlreadyExistsException. It signals a race or an existing database the existence pre-check missed.
Source
Thrown at flink/v2.1/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
- Treat as benign if the database already exists — retry the query; the database is now present.
- Pre-create the database before submitting jobs (e.g. CREATE DATABASE IF NOT EXISTS in Flink SQL or via the Iceberg catalog API).
- Serialize job startup so concurrent writers don't race on database creation.
Example fix
// before (SQL, racing jobs) CREATE TABLE iceberg_db.my_table ...; // each job auto-creates iceberg_db // after CREATE DATABASE IF NOT EXISTS iceberg_db; CREATE TABLE iceberg_db.my_table ...;
Defensive patterns
Strategy: try-catch
Validate before calling
if (!flinkCatalog.databaseExists(dbName)) { /* pre-create once at deployment time */ } Try / catch
try {
flinkCatalog.createDatabase(db, new CatalogDatabaseImpl(Maps.newHashMap(), null), true);
} catch (DatabaseAlreadyExistException e) {
// benign: another worker created it; proceed
} Prevention
- Pre-create databases in deployment scripts before starting jobs.
- Use ignoreIfExists=true when creating databases programmatically.
- Avoid multiple concurrent jobs auto-creating the same fresh database.
When it happens
Trigger: createTableLoader (invoked from createDynamicTableSource/createDynamicTableSink) when databaseExists(catalogDatabase) returned false but flinkCatalog.createDatabase then throws DatabaseAlreadyExistException — typically a concurrent job creating the same database.
Common situations: Multiple Flink jobs/queries starting simultaneously against a fresh Iceberg catalog and racing to create the same database; stale metadata in the factory's cached catalog view.
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
- 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
- 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/68ee7436c2913f99.
Report an issue: GitHub.