apache/iceberg · error · TableAlreadyExistException
TableAlreadyExistException
Error message
TableAlreadyExistException
What it means
Thrown by FlinkCatalog.renameTable when the target table name already exists in the Iceberg catalog (AlreadyExistsException), wrapped into Flink's TableAlreadyExistException. Iceberg's rename does not overwrite existing targets.
Solutions
- Choose a target name that does not already exist, or drop/rename the existing target first.
- Check tableExists on the target ObjectPath before renaming.
- Catch TableAlreadyExistException and handle the collision in application logic.
Example fix
// before
flinkCatalog.renameTable(new ObjectPath("db", "old"), "existing", false);
// after
ObjectPath target = new ObjectPath("db", "existing");
if (!flinkCatalog.tableExists(target)) {
flinkCatalog.renameTable(new ObjectPath("db", "old"), "existing", false);
} Defensive patterns
Strategy: validation
Validate before calling
ObjectPath target = new ObjectPath(db, newName);
if (flinkCatalog.tableExists(target)) { throw new IllegalStateException("target exists: " + target); } Try / catch
try {
flinkCatalog.renameTable(tablePath, newName, false);
} catch (TableAlreadyExistException e) {
// resolve collision: pick a new name or archive existing target
} Prevention
- Check the target name does not exist before rename
- Use unique, generated target names (timestamp+suffix)
- Catch the exception in automated pipelines to resolve collisions
When it happens
Trigger: Calling renameTable to a newTableName that already exists in the same database, with no pre-check.
Common situations: Retrying a partially completed rename; automated jobs generating colliding target names (e.g. timestamped names that already exist); attempting to swap tables by renaming over an existing one.
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
- Can not alter the default database when the iceberg catalog…
- Can not alter the default database when the iceberg catalog…
- Can not alter the default database when the iceberg catalog…
- Cannot create the table with 'connector'='iceberg' table…
- Cannot move view between catalogs: from=
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/7e451ebb33f373c8.
Report an issue: GitHub.
Appendix: source
Thrown at flink/v2.3/flink/src/main/java/org/apache/iceberg/flink/FlinkCatalog.java:408
if (!ignoreIfNotExists) {
throw new TableNotExistException(getName(), tablePath, e);
}
}
}
@Override
public void renameTable(ObjectPath tablePath, String newTableName, boolean ignoreIfNotExists)
throws TableNotExistException, TableAlreadyExistException, CatalogException {
try {
icebergCatalog.renameTable(
toIdentifier(tablePath),
toIdentifier(new ObjectPath(tablePath.getDatabaseName(), newTableName)));
} catch (org.apache.iceberg.exceptions.NoSuchTableException e) {
if (!ignoreIfNotExists) {
throw new TableNotExistException(getName(), tablePath, e);
}
} catch (AlreadyExistsException e) {
throw new TableAlreadyExistException(getName(), tablePath, e);
}
}
@Override
public void createTable(ObjectPath tablePath, CatalogBaseTable table, boolean ignoreIfExists)
throws CatalogException, TableAlreadyExistException {
// Creating Iceberg table using connector is allowed only when table is created using LIKE
if (Objects.equals(
table.getOptions().get(FlinkCreateTableOptions.CONNECTOR_PROPS_KEY),
FlinkDynamicTableFactory.FACTORY_IDENTIFIER)
&& table.getOptions().get(FlinkCreateTableOptions.SRC_CATALOG_PROPS_KEY) == null) {
throw new IllegalArgumentException(
"Cannot create the table with 'connector'='iceberg' table property in "
+ "an iceberg catalog, Please create table with 'connector'='iceberg' property in a non-iceberg catalog or "
+ "create table without 'connector'='iceberg' related properties in an iceberg table.");
}
Preconditions.checkArgument(View on GitHub (pinned to 86d9c8fc54)