apache/iceberg · error · UnsupportedOperationException

Unknown move type:

Error message

Unknown move type: 

What it means

When applying schema moves (Move.first, Move.before, Move.after) during SchemaUpdate.commit, an exhaustive switch over move.type() handles the known kinds. Any Move implementation outside the three supported kinds reaches the default branch and throws UnsupportedOperationException. This guards against future or custom move types the reordering logic does not implement.

Source

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

          break;

        case BEFORE:
          Types.NestedField before =
              Iterables.find(reordered, field -> field.fieldId() == move.referenceFieldId());
          int beforeIndex = reordered.indexOf(before);
          // insert the new node at the index of the existing node
          reordered.add(beforeIndex, toMove);
          break;

        case AFTER:
          Types.NestedField after =
              Iterables.find(reordered, field -> field.fieldId() == move.referenceFieldId());
          int afterIndex = reordered.indexOf(after);
          reordered.add(afterIndex + 1, toMove);
          break;

        default:
          throw new UnsupportedOperationException("Unknown move type: " + move.type());
      }
    }

    return reordered;
  }

  /** Represents a requested column move in a struct. */
  private static class Move {
    private enum MoveType {
      FIRST,
      BEFORE,
      AFTER
    }

    @Override
    public String toString() {
      String suffix = "";
      if (type != MoveType.FIRST) {

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Ensure the client library version producing the Move matches the version applying the update
  2. Only construct moves via updateSchema().moveFirst/moveBefore/moveAfter
  3. Upgrade iceberg-core so all Move types are supported
Defensive patterns

Strategy: try-catch

Validate before calling

if (move.type() != Move.MoveType.FIRST && move.type() != Move.MoveType.BEFORE && move.type() != Move.MoveType.AFTER) { throw new IllegalArgumentException("Unsupported move type"); }

Try / catch

try { update.apply(); } catch (UnsupportedOperationException e) { if (e.getMessage().startsWith("Unknown move type")) { /* version mismatch: upgrade client */ } else { throw e; } }

Prevention

When it happens

Trigger: Applying a Move whose type() is not FIRST, BEFORE, or AFTER — normally only possible with a custom Move implementation or a version mismatch where a newer move kind is passed to an older SchemaUpdate.

Common situations: Mixed client/server versions during rolling upgrades; custom TableOperations or wrapped Move objects from another Iceberg-compatible implementation.

Related errors


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