apache/iceberg · error · IllegalArgumentException

Cannot add fields to map keys:

Error message

Cannot add fields to map keys: 

What it means

Map key fields cannot have child fields added — keys must be primitive types, and the hidden key field is not a valid parent for new nested fields. If SchemaUpdate.apply sees the map key's field ID in parentToAddedIds (i.e. some update attempted to add a field under the key), it throws this IllegalArgumentException.

Source

Thrown at core/src/main/java/org/apache/iceberg/SchemaUpdate.java:722

      }

      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) {
        return map;
      }

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Add fields only under struct-typed parents (top-level schema or nested structs), never under map key/value field IDs
  2. Filter parent candidates to fields whose type is Types.StructType

Example fix

// before
updateSchema.addColumn(mapKeyFieldId, "extra", Types.StringType.get()); // throws
// after
updateSchema.addColumn(null, "meta", Types.StructType.of(...)); // add sibling struct field instead
Defensive patterns

Strategy: validation

Validate before calling

Types.MapType map = ...;
int keyId = map.fields().get(0).fieldId();
if (Objects.equals(parentFieldId, keyId)) throw new IllegalArgumentException("Cannot add child fields to a map key; keys must be primitive");

Type guard

static boolean isStructParent(Schema schema, int parentFieldId) {
  Types.NestedField f = schema.findField(parentFieldId) != null ? schema.findField(parentFieldId) : findNested(schema, parentFieldId);
  return f != null && f.type() instanceof Types.StructType;
}

Try / catch

try {
  updateSchema.apply();
} catch (IllegalArgumentException e) {
  if (e.getMessage().startsWith("Cannot add fields to map keys")) throw new IllegalStateException("Parent field must be a struct, not a map key", e);
  throw e;
}

Prevention

When it happens

Trigger: Calling updateSchema.addColumn(keyFieldId, name, type) or move operations targeting the map key field ID as a parent, or generic tooling that treats every nested field ID as an addable parent.

Common situations: Automation that collects all struct-like field IDs as candidate parents and mistakenly includes map key IDs; misunderstanding the hidden map key field as a struct.

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


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/04dbd1645c4369d2. Report an issue: GitHub.