prestodb/presto · error · PrestoException

COLUMN_NOT_FOUND

COLUMN_NOT_FOUND

Error message

Unknown field %s

What it means

Presto throws this PrestoException when a column listed in a table's metadata (or referenced by the statement) has no corresponding ConnectorColumnHandle in the handles returned by the connector's getColumnHandles. It means the connector knows the column name but cannot map it to a physical column handle, i.e. the catalog/schema/table metadata and the column handles are out of sync.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/sql/analyzer/StatementAnalyzer.java:2493

            Map<String, ColumnHandle> columnHandles = tableColumnsMetadata.getColumnHandles();

            // TODO: discover columns lazily based on where they are needed (to support connectors that can't enumerate all tables)
            ImmutableList.Builder<Field> fields = ImmutableList.builder();

            for (ColumnMetadata column : columnsMetadata) {
                Field field = Field.newQualified(
                        Optional.empty(),
                        table.getName(),
                        Optional.of(column.getName()),
                        column.getType(),
                        column.isHidden(),
                        Optional.of(name),
                        Optional.of(column.getName()),
                        false);
                fields.add(field);
                ColumnHandle columnHandle = columnHandles.get(column.getName());
                if (columnHandle == null) {
                    throw new PrestoException(COLUMN_NOT_FOUND, format("Unknown field %s", field));
                }
                analysis.setColumn(field, columnHandle);
                analysis.addSourceColumns(field, ImmutableSet.of(new SourceColumn(name, column.getName())));
            }

            boolean isMergeIntoStatement = statement instanceof Merge && ((Merge) statement).getTargetTable().equals(table);
            if (isMergeIntoStatement) {
                // Add the target table row id field used to process the MERGE command.
                ColumnHandle targetTableRowIdColumnHandle = metadata.getMergeTargetTableRowIdColumnHandle(session, tableHandle.get());
                Type targetTableRowIdType = metadata.getColumnMetadata(session, tableHandle.get(), targetTableRowIdColumnHandle).getType();
                Field targetTableRowIdField = Field.newUnqualified(table.getLocation(), "$target_table_row_id", targetTableRowIdType);
                fields.add(targetTableRowIdField);
                analysis.setColumn(targetTableRowIdField, targetTableRowIdColumnHandle);
            }

            analysis.registerTable(table, tableHandle.get());

            List<Field> outputFields = fields.build();

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Refresh the connector metadata cache (invalidate cache or restart the coordinator) and retry the query
  2. Verify the column actually exists: run SHOW COLUMNS FROM catalog.schema.table and adjust the query
  3. Recreate/sync the table metadata if the connector's column handles are out of sync (e.g. MSCK REPAIR / connector-specific sync)
  4. Upgrade or fix the connector plugin if getColumnHandles inconsistently omits declared columns

Example fix

// before
SELECT deleted_col FROM catalog.schema.events; -- column dropped externally
// after
SHOW COLUMNS FROM catalog.schema.events;
SELECT existing_col FROM catalog.schema.events;
Defensive patterns

Strategy: validation

Validate before calling

-- confirm the column exists before querying
SHOW COLUMNS FROM catalog.schema.table;

Try / catch

try {
    return session.execute(query);
} catch (PrestoException e) {
    if (e.getErrorCode().getCode() == COLUMN_NOT_FOUND.getCode()) {
        // refresh metadata cache / re-run SHOW COLUMNS and rebuild query
    }
    throw e;
}

Prevention

When it happens

Trigger: Querying a table whose metadata reports a column for which metadata.getColumnHandles returns no entry — typically after the connector's metadata changed underneath a cached or stale schema, or for synthetic/internal columns the connector does not expose as handles (e.g. hidden or deleted columns in connectors like Iceberg/Delta/Hive during snapshot evolution).

Common situations: Concurrent table schema evolution (DROP COLUMN) while a query plan is being built; connector metadata cache holding an old column list; querying a table through a connector version that changed column handle naming; MERGE/UPDATE statements referencing a column removed on the writer.

Related errors


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