prestodb/presto · error · PrestoException
ALREADY_EXISTS
ALREADY_EXISTS
Error message
Branch %s already exists in table %s
What it means
Thrown when creating a branch that already exists as a reference on the Iceberg table and replace semantics were not requested. Iceberg refuses to create a duplicate ref, so the connector fails with ALREADY_EXISTS.
Source
Thrown at presto-iceberg/src/main/java/com/facebook/presto/iceberg/IcebergAbstractMetadata.java:1189
return;
}
Optional<Long> targetSnapshotId = tableVersion
.map(version -> getSnapshotIdForTableVersion(icebergTable, version))
.or(() -> Optional.ofNullable(icebergTable.currentSnapshot()).map(Snapshot::snapshotId));
ManageSnapshots manageSnapshots = icebergTable.manageSnapshots();
if (replace && branchExists) {
targetSnapshotId.ifPresent(snapshotId -> manageSnapshots.replaceBranch(branchName, snapshotId));
}
else if (!branchExists) {
if (targetSnapshotId.isPresent()) {
manageSnapshots.createBranch(branchName, targetSnapshotId.get());
}
else {
manageSnapshots.createBranch(branchName);
}
}
else {
throw new PrestoException(ALREADY_EXISTS, format("Branch %s already exists in table %s", branchName, icebergTableHandle.getSchemaTableName().getTableName()));
}
// Apply retention policies if specified
retainDays.ifPresent(retainDs -> manageSnapshots.setMaxRefAgeMs(branchName, ofDays(retainDs).toMillis()));
minSnapshotsToKeep.ifPresent(minSnapshots -> manageSnapshots.setMinSnapshotsToKeep(branchName, minSnapshots));
maxSnapshotAgeDays.ifPresent(maxAgeDays -> manageSnapshots.setMaxSnapshotAgeMs(branchName, ofDays(maxAgeDays).toMillis()));
manageSnapshots.commit();
}
@Override
public void createTag(
ConnectorSession session,
ConnectorTableHandle tableHandle,
String tagName,
boolean replace,
boolean ifNotExists,
Optional<ConnectorTableVersion> tableVersion,
Optional<Long> retainDays)
{View on GitHub (pinned to 55bb57d202)
Solutions
- Use CREATE BRANCH IF NOT EXISTS (or the replace option) so an existing branch doesn't fail the statement.
- Pick a new unique branch name.
- If the intent is to re-point the branch, use the replace/REPLACE form instead of plain create.
Example fix
// before ALTER TABLE t CREATE BRANCH etl; -- already exists // after ALTER TABLE t CREATE BRANCH IF NOT EXISTS etl;
Defensive patterns
Strategy: validation
Validate before calling
-- check branch existence before creating SELECT * FROM "t$refs" WHERE name = 'etl' AND type = 'BRANCH';
Try / catch
try { createBranch(...); }
catch (PrestoException e) { if (ALREADY_EXISTS.equals(e.getErrorCode())) { /* reuse, replace, or rename */ } } Prevention
- Use CREATE BRANCH IF NOT EXISTS for idempotent pipelines
- Generate unique branch names per run (date/uuid suffix)
- Centralize branch lifecycle in one job to avoid races
When it happens
Trigger: ALTER TABLE ... CREATE BRANCH <name> where a branch with that name is already present in icebergTable.refs() (without REPLACE).
Common situations: Re-running an idempotency-scripted CREATE BRANCH without IF NOT EXISTS; naming collision with an existing tag or branch created by CI pipelines; concurrent creation by two sessions.
Related errors
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/d03f9f37d43b493d.
Report an issue: GitHub.