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

  1. Use CREATE BRANCH IF NOT EXISTS (or the replace option) so an existing branch doesn't fail the statement.
  2. Pick a new unique branch name.
  3. 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

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.