prestodb/presto · error · PrestoException

ALREADY_EXISTS

ALREADY_EXISTS

Error message

errorDetail.errorMessage()

What it means

propagateErrorDetailToPrestoException maps an ErrorDetail returned by Glue batch operations onto Presto exceptions: an AlreadyExistsException code becomes ALREADY_EXISTS with Glue's message, EntityNotFoundException becomes TableNotFoundException, anything else becomes HIVE_METASTORE_ERROR. So this error means the Glue service rejected the operation because the target (table or partition) already exists.

Source

Thrown at presto-hive-metastore/src/main/java/com/facebook/presto/hive/metastore/glue/GlueHiveMetastore.java:1274

            propagateErrorDetailToPrestoException(databaseName, tableName, errorDetail);
        }
    }

    private static void propagateBatchUpdatePartitionErrorToPrestoException(String databaseName, String tableName, List<BatchUpdatePartitionFailureEntry> failureEntries)
    {
        if (failureEntries != null && !failureEntries.isEmpty()) {
            ErrorDetail errorDetail = failureEntries.get(0).errorDetail();
            propagateErrorDetailToPrestoException(databaseName, tableName, errorDetail);
        }
    }

    private static void propagateErrorDetailToPrestoException(String databaseName, String tableName, ErrorDetail errorDetail)
    {
        String glueExceptionCode = errorDetail.errorCode();

        switch (glueExceptionCode) {
            case "AlreadyExistsException":
                throw new PrestoException(ALREADY_EXISTS, errorDetail.errorMessage());
            case "EntityNotFoundException":
                throw new TableNotFoundException(new SchemaTableName(databaseName, tableName), errorDetail.errorMessage());
            default:
                throw new PrestoException(HIVE_METASTORE_ERROR, errorDetail.errorCode() + ": " + errorDetail.errorMessage());
        }
    }

    @Override
    public void dropPartition(MetastoreContext metastoreContext, String databaseName, String tableName, List<String> parts, boolean deleteData)
    {
        Table table = getTableOrElseThrow(metastoreContext, databaseName, tableName);
        Partition partition = getPartition(metastoreContext, databaseName, tableName, parts)
                .orElseThrow(() -> new PartitionNotFoundException(new SchemaTableName(databaseName, tableName), parts));

        try {
            awsSyncRequest(
                    glueClient::deletePartition,
                    DeletePartitionRequest.builder()

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Treat ALREADY_EXISTS as success when the existing object matches the desired definition (upsert semantics): check getObject first and skip creation.
  2. Use Glue's existence check (getTable / getPartition) before create calls in sync jobs.
  3. If the existing object is wrong, explicitly delete/recreate it (or use UpdateTable) rather than blind create.
  4. Catch PrestoException with code ALREADY_EXISTS around batch operations and reconcile per-item from errorDetails.

Example fix

// before
metastore.createTable(context, newTable()); // fails if Glue table exists
// after
if (metastore.getTable(context, db, tableName).isEmpty()) {
    metastore.createTable(context, newTable());
}
Defensive patterns

Strategy: validation

Validate before calling

boolean tableExists = metastore.getTable(ctx, db, tableName).isPresent();
if (!tableExists) { metastore.createTable(ctx, newTableDefinition()); }

Try / catch

try {
    glueBatchCreate();
}
catch (PrestoException e) {
    if (e.getErrorCode().getName().equals("ALREADY_EXISTS")) { reconcileExisting(); /* compare and skip/update */ }
    else if (e instanceof TableNotFoundException) { createParentAndRetry(); }
    else { throw e; }
}

Prevention

When it happens

Trigger: Batch Glue calls (createTable/batchCreatePartition style operations) whose error details contain errorCode 'AlreadyExistsException'; creating a Glue table or partition that already exists, surfaced via errorDetails rather than a direct exception.

Common situations: Re-running CREATE TABLE against Glue after a partial failure; idempotency-breaking deployment scripts; concurrent creators of the same Glue table/partition; syncing tools that assume-empty targets.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/f3f9c2cfeeb58a96. Report an issue: GitHub.