apache/iceberg · error · IllegalArgumentException
Cannot update map keys:
Error message
Cannot update map keys:
What it means
Map keys in Iceberg are immutable identity components of the map type; the schema evolution rules prohibit updating (renaming, retyping, re-required-ness) the hidden key field. If SchemaUpdate.apply finds the map key's field ID in the updates map, it throws this IllegalArgumentException.
Source
Thrown at core/src/main/java/org/apache/iceberg/SchemaUpdate.java:720
if (isElementOptional == elementField.isOptional() && list.elementType() == elementType) {
return list;
}
if (isElementOptional) {
return Types.ListType.ofOptional(list.elementId(), elementType);
} else {
return Types.ListType.ofRequired(list.elementId(), elementType);
}
}
@Override
public Type map(Types.MapType map, Type kResult, Type valueResult) {
// if any updates are intended for the key, throw an exception
int keyId = map.fields().get(0).fieldId();
if (deletes.contains(keyId)) {
throw new IllegalArgumentException("Cannot delete map keys: " + map);
} else if (updates.containsKey(keyId)) {
throw new IllegalArgumentException("Cannot update map keys: " + map);
} else if (parentToAddedIds.containsKey(keyId)) {
throw new IllegalArgumentException("Cannot add fields to map keys: " + map);
} else if (!map.keyType().equals(kResult)) {
throw new IllegalArgumentException("Cannot alter map keys: " + map);
}
// use field to apply updates to the value
Types.NestedField valueField = map.fields().get(1);
Type valueType = field(valueField, valueResult);
if (valueType == null) {
throw new IllegalArgumentException("Cannot delete value type from map: " + map);
}
Types.NestedField valueUpdate = updates.get(valueField.fieldId());
boolean isValueOptional =
valueUpdate != null ? valueUpdate.isOptional() : map.isValueOptional();
if (isValueOptional == map.isValueOptional() && map.valueType() == valueType) {View on GitHub (pinned to 86d9c8fc54)
Solutions
- Do not update map key fields; rebuild the map column with a new key type by dropping and re-adding the column (acknowledging data rewrite semantics)
- Restrict updateColumn/require calls to non-key field IDs
Example fix
// before updateSchema.updateColumn(mapKeyFieldId, Types.LongType.get()); // throws // after updateSchema.delete(mapColumn.fieldId()); updateSchema.addColumn(parent, name, Types.MapType.ofOptional(keyId, valueId, Types.LongType.get(), valueType));
Defensive patterns
Strategy: validation
Validate before calling
Types.MapType map = ...;
int keyId = map.fields().get(0).fieldId();
if (requestedUpdates.containsKey(keyId)) throw new IllegalArgumentException("Map keys cannot be updated; rebuild the map column instead"); Type guard
static boolean updateTouchesMapKey(UpdateSchema update, Types.MapType map) {
int keyId = map.fields().get(0).fieldId();
return update.appliedUpdates().stream().anyMatch(u -> u instanceof UpdateColumn && ((UpdateColumn) u).fieldId() == keyId);
} Try / catch
try {
updateSchema.apply();
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Cannot update map keys")) throw new IllegalStateException("Drop and re-add the map with the desired key type (requires data rewrite)", e);
throw e;
} Prevention
- Exclude map key IDs from bulk updateColumn/requireOptional/rename sweeps
- To change a key type, drop and re-add the whole map column
- Treat key field IDs (and value IDs) as reserved and untouchable
When it happens
Trigger: Calling updateSchema.updateColumn(keyFieldId, ...) / requireOptional(keyFieldId) / rename(keyFieldId, ...) where the target ID is a map key's internal field ID.
Common situations: Bulk update scripts applying type-widening or optionality changes to every nested field ID, accidentally including map key IDs; attempts to 'widen' key types via generic update tooling.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Cannot delete element type from list:
- Cannot delete map keys:
- Cannot add fields to map keys:
- Cannot alter map keys:
- Unsorted order ID must be 0
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/1e930d8f14733f65.
Report an issue: GitHub.