prestodb/presto · error · PrestoException
ICEBERG_MISSING_COLUMN
ICEBERG_MISSING_COLUMN
Error message
Column %s not found in delegate column map
What it means
IcebergUpdateablePageSource wraps a delegate page source (e.g. for UPDATE with row lineage). During output-column setup, each requested output column must exist in the delegate's columnToIndex map keyed by ColumnIdentity. When an output column is absent from the underlying split's schema, the connector throws ICEBERG_MISSING_COLUMN, indicating the reader cannot supply that column.
Source
Thrown at presto-iceberg/src/main/java/com/facebook/presto/iceberg/IcebergUpdateablePageSource.java:205
int lastUpdatedSeqIdx = -1;
int rowPosIdx = -1;
for (int i = 0; i < outputColumns.size(); i++) {
IcebergColumnHandle outputColumn = outputColumns.get(i);
if (outputColumn.isUpdateRowIdColumn() || outputColumn.isMergeTargetTableRowIdColumn()) {
continue;
}
if (outputColumn.isRowIdColumn()) {
// Map to delegate index for reading file values, but also track output index for fallback
rowLineageIdx = i;
}
if (outputColumn.isLastUpdatedSequenceNumberColumn()) {
lastUpdatedSeqIdx = i;
}
if (!columnToIndex.containsKey(outputColumn.getColumnIdentity())) {
throw new PrestoException(ICEBERG_MISSING_COLUMN, format("Column %s not found in delegate column map", outputColumn));
}
else {
outputColumnToDelegateMapping[i] = columnToIndex.get(outputColumn.getColumnIdentity());
}
}
this.rowLineageRowIdOutputIndex = rowLineageIdx;
this.lastUpdatedSeqOutputIndex = lastUpdatedSeqIdx;
// Find the delegate index for ROW_POSITION (needed for _row_id = firstRowId + _pos fallback)
if (rowLineageIdx >= 0 && firstRowId >= 0) {
for (int i = 0; i < delegateColumns.size(); i++) {
if (delegateColumns.get(i).isRowPositionColumn()) {
rowPosIdx = i;
break;
}
}
}
this.rowPositionDelegateIndex = rowPosIdx;View on GitHub (pinned to 55bb57d202)
Solutions
- Re-run the query so the plan and splits reflect the current table schema.
- Check for concurrent ALTER TABLE operations and retry after they complete.
- Clear/refresh metadata caches and, if reproducible, verify all nodes run the same Presto version.
- Inspect the update assignment and column list to ensure no dropped/renamed column is still referenced.
Example fix
// before (stale plan after RENAME COLUMN col_a -> col_b) UPDATE t SET col_a = 'x' WHERE ... // after UPDATE t SET col_b = 'x' WHERE ... -- re-planned against current schema
Defensive patterns
Strategy: try-catch
Validate before calling
// before running UPDATE, verify the assignment columns still exist
for (String col : updateColumns) {
if (!currentTableSchema.getColumnNames().contains(col)) {
throw new IllegalStateException("Column missing from current schema: " + col);
}
} Try / catch
try {
pageSource = createUpdateablePageSource(...);
} catch (PrestoException e) {
if (e.getErrorCode() == ICEBERG_MISSING_COLUMN.toErrorCode()) {
// schema changed under us; invalidate plan/split and retry once
invalidatePlanCache();
pageSource = createUpdateablePageSource(...);
} else { throw e; }
} Prevention
- Avoid concurrent ALTER TABLE (add/rename/drop column) while UPDATEs run
- Re-plan queries after schema changes instead of reusing cached plans
- Keep all Presto nodes on the same version
- Verify column names in UPDATE statements against the live schema
When it happens
Trigger: Opening an updateable page source where an output column (often the $row_id/last-updated-sequence columns or a normal column) is not present in the delegate's column map — e.g. the table schema changed (column added/renamed) after the query plan was built, or the split metadata is stale.
Common situations: Concurrent ALTER TABLE ADD/RENAME COLUMN while an UPDATE runs; cached plans referencing old schema; split/plan produced by a different coordinator version than the worker executing it.
Related errors
- ICEBERG_MISSING_COLUMN
- CORRUPT_PAGE
- currentFieldIndexToWrite is not valid
- Request has different number of fields than column handles:
- HIVE_INVALID_ENCRYPTION_METADATA
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/9d2a5a6949d5d471.
Report an issue: GitHub.