apache/iceberg · error · IllegalArgumentException
Unknown position for reorder: ${update.position()}
Error message
Unknown position for reorder: ${update.position()} What it means
Thrown by the private apply(UpdateSchema, TableChange.UpdateColumnPosition) helper when update.position() is neither TableChange.After nor TableChange.First. There is no mapping for other position types, so column reordering cannot proceed.
Source
Thrown at spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/Spark3Util.java:242
}
}
return pendingUpdate;
}
private static void apply(UpdateSchema pendingUpdate, TableChange.UpdateColumnPosition update) {
Preconditions.checkArgument(update.position() != null, "Invalid position: null");
if (update.position() instanceof TableChange.After) {
TableChange.After after = (TableChange.After) update.position();
String referenceField = peerName(update.fieldNames(), after.column());
pendingUpdate.moveAfter(DOT.join(update.fieldNames()), referenceField);
} else if (update.position() instanceof TableChange.First) {
pendingUpdate.moveFirst(DOT.join(update.fieldNames()));
} else {
throw new IllegalArgumentException("Unknown position for reorder: " + update.position());
}
}
private static void apply(UpdateSchema pendingUpdate, TableChange.AddColumn add) {
Preconditions.checkArgument(
add.isNullable(),
"Incompatible change: cannot add required column: %s",
leafName(add.fieldNames()));
if (add.defaultValue() != null) {
throw new UnsupportedOperationException(
String.format(
"Cannot add column %s since setting default values in Spark is currently unsupported",
leafName(add.fieldNames())));
}
Type type = SparkSchemaUtil.convert(add.dataType());
pendingUpdate.addColumn(
parentName(add.fieldNames()), leafName(add.fieldNames()), type, add.comment());View on GitHub (pinned to 86d9c8fc54)
Solutions
- Only construct After or First positions when issuing UpdateColumnPosition changes
- Upgrade Iceberg if a new Position type was introduced upstream
- Add an explicit branch for the new Position type in local integration code
Example fix
// before
TableChange.UpdateColumnPosition upd = TableChange.updateColumnPosition(
new String[]{"col"}, new MyCustomPosition());
// after
TableChange.UpdateColumnPosition upd = TableChange.updateColumnPosition(
new String[]{"col"}, TableChange.ColumnPosition.after("other")); Defensive patterns
Strategy: validation
Validate before calling
if (!(position instanceof TableChange.After) && !(position instanceof TableChange.First)) {
throw new IllegalArgumentException("Position must be After or First");
} Try / catch
try {
apply(update);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Unknown position for reorder")) {
// convert or drop the position
}
} Prevention
- Only use TableChange.first()/after(col) helpers to build positions
- Avoid custom Position implementations in integration code
- Validate position types before issuing UpdateColumnPosition
When it happens
Trigger: Calling ALTER TABLE ... ALTER COLUMN x AFTER/FIRST handling code with a position object that is neither After nor First — typically a custom or future TableChange.Position subtype.
Common situations: Custom SQL engines emitting their own Position implementations; forward-compatibility issues after a Spark/Iceberg upgrade adds a new Position subtype.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Unknown position for reorder:
- Unknown position for reorder: ${update.position()}
- Spark does not support time fields
- Unsupported type:
- Encountered an unsupported ORC type during a write from Spar
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/dd7a1c5c2b36db7f.
Report an issue: GitHub.