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

  1. Only construct After or First positions when issuing UpdateColumnPosition changes
  2. Upgrade Iceberg if a new Position type was introduced upstream
  3. 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

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


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