apache/iceberg · error · org.apache.flink.table.catalog.exceptions.AlreadyExistsException
Database %s already exists in the iceberg catalog %s.
Error message
Database %s already exists in the iceberg catalog %s.
What it means
During dynamic table creation, FlinkDynamicTableFactory.createTableLoader tries to create the database in the external catalog with ignoreIfNotExists semantics. If createDatabase nevertheless throws DatabaseAlreadyExistException (race with another job/client), it is converted to AlreadyExistsException with 'Database %s already exists in the iceberg catalog %s.'
Source
Thrown at flink/v2.3/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
- Verify the database exists and reuse it instead of creating it
- Serialize database creation (create once via a setup job or catalog CLI) before submitting jobs
- Catch AlreadyExistsException and treat it as success if the database is the one you intended
- Use distinct database names per environment/team to avoid collisions
Example fix
// before
flinkCatalog.createDatabase(db, new CatalogDatabaseImpl(new HashMap<>(), null), true);
// after
if (!flinkCatalog.databaseExists(db)) {
try {
flinkCatalog.createDatabase(db, new CatalogDatabaseImpl(new HashMap<>(), null), true);
} catch (DatabaseAlreadyExistException e) {
// another client created it concurrently; safe to proceed
}
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!catalog.databaseExists(db)) { /* create */ } Try / catch
try { catalog.createDatabase(db, new CatalogDatabaseImpl(new HashMap<>(), null), true); } catch (DatabaseAlreadyExistException | AlreadyExistsException e) { /* idempotent success */ } Prevention
- Create databases upfront in a single setup step
- Use ignoreIfExists semantics and treat AlreadyExists as success
- Avoid multiple jobs creating the same database concurrently
When it happens
Trigger: Two concurrent Flink jobs/queries both creating the same database via CREATE TABLE IF NOT EXISTS paths; a race where the database is created between the databaseExists check and createDatabase call.
Common situations: Parallel job deployments against a shared REST/Hive catalog; retrying a failed deployment while another client already created the database; sandbox namespaces shared across teams.
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
- Table was created concurrently: %s
- Table already exists: %s
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/281947fa6204770c.
Report an issue: GitHub.