prestodb/presto · error · PrestoException
ALREADY_EXISTS
ALREADY_EXISTS
Error message
Column already exists: ${columnName} What it means
FileHiveMetastore.addColumn throws this because the target column name is already present in the table's schema (checked via oldTable.getColumn(columnName).isPresent()). The file-based metastore stores schema as JSON files and enforces uniqueness of column names within a table at alterTable time. This is a client-side validation error: you asked to add a column that already exists instead of using rename or modifyColumn.
Source
Thrown at presto-hive-metastore/src/main/java/com/facebook/presto/hive/metastore/file/FileHiveMetastore.java:546
requireNonNull(newTableName, "newTableName is null");
getRequiredDatabase(metastoreContext, newDatabaseName);
// verify new table does not exist
verifyTableNotExists(metastoreContext, newDatabaseName, newTableName);
Path metadataDirectory = getTableMetadataDirectory(databaseName, tableName);
Path newMetadataDirectory = getTableMetadataDirectory(newDatabaseName, newTableName);
renameTable(metadataDirectory, newMetadataDirectory);
return EMPTY_RESULT;
}
@Override
public synchronized MetastoreOperationResult addColumn(MetastoreContext metastoreContext, String databaseName, String tableName, String columnName, HiveType columnType, String columnComment)
{
alterTable(databaseName, tableName, oldTable -> {
if (oldTable.getColumn(columnName).isPresent()) {
throw new PrestoException(ALREADY_EXISTS, "Column already exists: " + columnName);
}
return oldTable.withDataColumns(ImmutableList.<Column>builder()
.addAll(oldTable.getDataColumns())
.add(new Column(columnName, columnType, Optional.ofNullable(columnComment), Optional.empty()))
.build());
});
return EMPTY_RESULT;
}
@Override
public synchronized MetastoreOperationResult renameColumn(MetastoreContext metastoreContext, String databaseName, String tableName, String oldColumnName, String newColumnName)
{
alterTable(databaseName, tableName, oldTable -> {
if (oldTable.getColumn(newColumnName).isPresent()) {
throw new PrestoException(ALREADY_EXISTS, "Column already exists: " + newColumnName);
}View on GitHub (pinned to 55bb57d202)
Solutions
- Check the existing schema first (getTableColumnNames / SHOW COLUMNS) and skip the add if the column already exists.
- If the intent was to change the column type or comment, use modifyColumn instead of addColumn.
- Make migration scripts idempotent: wrap the addColumn call in an existence check or catch ALREADY_EXISTS and treat as success.
- If a stale cached table view caused a false positive, re-fetch the table metadata and retry once.
Example fix
// before
metastore.addColumn(context, db, table, "extra_col", HiveType.HIVE_INT, null);
// after
Table table = metastore.getTable(context, db, table).orElseThrow(...);
if (table.getColumn("extra_col").isEmpty()) {
metastore.addColumn(context, db, table, "extra_col", HiveType.HIVE_INT, null);
} Defensive patterns
Strategy: validation
Validate before calling
boolean columnExists = metastore.getTable(metastoreContext, db, table)
.orElseThrow(() -> new TableNotFoundException(new SchemaTableName(db, table)))
.getColumn("extra_col").isPresent();
if (!columnExists) { metastore.addColumn(metastoreContext, db, table, "extra_col", HiveType.HIVE_INT, null); } Try / catch
try {
metastore.addColumn(ctx, db, table, name, type, comment);
}
catch (PrestoException e) {
if (e.getErrorCode().getName().equals("ALREADY_EXISTS")) { /* treat as success */ }
else { throw e; }
} Prevention
- Always read the current table schema before schema-altering calls.
- Make DDL migration scripts idempotent (check-then-apply or catch-and-continue).
- Remember Presto identifiers are case-insensitive; compare names case-insensitively.
When it happens
Trigger: Calling Metastore.addColumn (directly or via ALTER TABLE ADD COLUMN) with a columnName that already appears in the table's data columns; re-running a non-idempotent migration script that adds the same column twice.
Common situations: Migration/ETL scripts executed twice; concurrent ALTER TABLE ADD COLUMN from two sessions on a table backed by FileHiveMetastore (schema is checked inside synchronized alterTable, but callers often pre-check and race); schema drift between an external Hive catalog and the Presto file metastore.
Related errors
- NOT_FOUND
- HIVE_COLUMN_ORDER_MISMATCH
- HIVE_METASTORE_ERROR
- Invalid Hive object for %s.%s
- SCHEMA_ALREADY_EXISTS
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/2403cc33c16a0289.
Report an issue: GitHub.