apache/iceberg · error · AlreadyExistsException
Table already exists: %s
Error message
Table already exists: %s
What it means
CatalogHandlers.stageTableCreate rejects a create-table request with AlreadyExistsException when a table with the same identifier already exists (catalog.tableExists check). Staged creates refuse to clobber existing tables; this maps to a 409-style conflict in REST semantics.
Source
Thrown at core/src/main/java/org/apache/iceberg/rest/CatalogHandlers.java:412
}
public static ListTablesResponse listTables(
Catalog catalog, Namespace namespace, String pageToken, String pageSize) {
List<TableIdentifier> results = catalog.listTables(namespace);
Pair<List<TableIdentifier>, String> page =
paginate(results, pageToken, Integer.parseInt(pageSize));
return ListTablesResponse.builder().addAll(page.first()).nextPageToken(page.second()).build();
}
public static LoadTableResponse stageTableCreate(
Catalog catalog, Namespace namespace, CreateTableRequest request) {
request.validate();
TableIdentifier ident = TableIdentifier.of(namespace, request.name());
if (catalog.tableExists(ident)) {
throw new AlreadyExistsException("Table already exists: %s", ident);
}
Map<String, String> properties = Maps.newHashMap();
properties.put("created-at", OffsetDateTime.now(ZoneOffset.UTC).toString());
properties.putAll(request.properties());
String location;
if (request.location() != null) {
location = request.location();
} else {
location =
catalog
.buildTable(ident, request.schema())
.withPartitionSpec(request.spec())
.withSortOrder(request.writeOrder())
.withProperties(properties)
.createTransaction()
.table()View on GitHub (pinned to 86d9c8fc54)
Solutions
- Check tableExists before creating, or catch AlreadyExistsException and reuse the table
- Use create-or-replace / create-or-ignore transaction semantics if intended
- Use unique (timestamped/suffixed) table names for repeated pipelines
- Find the duplicate request source (retries, schedulers) causing double creates
Example fix
// before
Table t = catalog.createTable(ident, schema); // throws if exists
// after
Table t = catalog.tableExists(ident)
? catalog.loadTable(ident)
: catalog.createTable(ident, schema); Defensive patterns
Strategy: try-catch
Validate before calling
if (catalog.tableExists(ident)) {
// load or skip
} else {
catalog.createTable(ident, schema);
} Try / catch
try {
catalog.createTable(ident, schema);
} catch (AlreadyExistsException e) {
table = catalog.loadTable(ident);
} Prevention
- Make table creation idempotent with exists-checks or create-or-replace
- Serialize setup jobs that create the same table
- Use deterministic table names in CI pipelines
When it happens
Trigger: Calling createTable/stageTableCreate (REST POST v1/namespaces/{ns}/tables) when a table with namespace + request.name() already exists.
Common situations: Retried requests after a first successful create; concurrent jobs creating the same table; re-running setup scripts without create-or-replace semantics.
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 already exists: %s
- Table with same name already exists: %s
- Cannot create namespace %s: already exists
- Namespace already exists: %s
- Table already exists: %s
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/a1a699bdb44da95d.
Report an issue: GitHub.