apache/iceberg · error · java.lang.UnsupportedOperationException

Altering schema is not supported in the old alterTable API.

Error message

Altering schema is not supported in the old alterTable API. To alter schema, use the other alterTable API and provide a list of TableChange's.

What it means

The deprecated/legacy Flink Catalog.alterTable(ObjectPath, CatalogTable, boolean) API cannot change a table's schema; FlinkCatalog.validateTableSchemaAndPartition compares the unresolved schemas of the existing and new CatalogTable and throws UnsupportedOperationException when they differ. Schema evolution must go through the TableChange-based alterTable API.

Source

Thrown at flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/FlinkCatalog.java:478

    try {
      icebergCatalog.createTable(
          toIdentifier(tablePath), icebergSchema, spec, location, properties.build());
    } catch (AlreadyExistsException e) {
      if (!ignoreIfExists) {
        throw new TableAlreadyExistException(getName(), tablePath, e);
      }
    }
  }

  private boolean isReservedProperty(String prop) {
    return FlinkCreateTableOptions.LOCATION_KEY.equalsIgnoreCase(prop)
        || FlinkCreateTableOptions.CONNECTOR_PROPS_KEY.equalsIgnoreCase(prop)
        || FlinkCreateTableOptions.SRC_CATALOG_PROPS_KEY.equalsIgnoreCase(prop);
  }

  private static void validateTableSchemaAndPartition(CatalogTable ct1, CatalogTable ct2) {
    if (!Objects.equals(ct1.getUnresolvedSchema(), ct2.getUnresolvedSchema())) {
      throw new UnsupportedOperationException(
          "Altering schema is not supported in the old alterTable API. "
              + "To alter schema, use the other alterTable API and provide a list of TableChange's.");
    }

    validateTablePartition(ct1, ct2);
  }

  private static void validateTablePartition(CatalogTable ct1, CatalogTable ct2) {
    if (!ct1.getPartitionKeys().equals(ct2.getPartitionKeys())) {
      throw new UnsupportedOperationException("Altering partition keys is not supported yet.");
    }
  }

  /**
   * This alterTable API only supports altering table properties.
   *
   * <p>Support for adding/removing/renaming columns cannot be done by comparing CatalogTable
   * instances, unless the Flink schema contains Iceberg column IDs.

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Use the TableChange-based alterTable: ALTER TABLE in Flink SQL (ALTER TABLE t ADD (c INT)) or catalog.alterTable(path, List<TableChange>, ignoreIfNotExists) with UpdateRequirements/UpdateOptions as appropriate.
  2. If only properties changed, verify the schema is byte-identical so the legacy API is safe, or migrate the call anyway.
  3. Upgrade the caller to Flink's newer catalog API surface that supports TableChange.

Example fix

// before
catalog.alterTable(path, tableWithNewColumn, false);
// after
catalog.alterTable(path, java.util.Arrays.asList(TableChange.addColumn("c", DataTypes.INT())), false);
Defensive patterns

Strategy: validation

Validate before calling

// compare schemas before legacy alterTable
if (!current.getUnresolvedSchema().equals(proposed.getUnresolvedSchema())) {
  useTableChangeApi = true;
}

Type guard

boolean schemaUnchanged(CatalogTable a, CatalogTable b) {
  return java.util.Objects.equals(a.getUnresolvedSchema(), b.getUnresolvedSchema());
}

Try / catch

try { catalog.alterTable(path, proposed, false); }
catch (UnsupportedOperationException e) {
  // fall back to TableChange-based alterTable
catalog.alterTable(path, schemaChanges, false);
}

Prevention

When it happens

Trigger: Calling alterTable(tablePath, newCatalogTable, ignoreIfNotExists) where newCatalogTable's unresolved schema differs from the current table's — e.g. adding, dropping, renaming, or retyping a column via full-table replacement.

Common situations: Older Flink job/framework code that still uses the legacy alterTable signature to add a column; hand-written migration scripts that rewrite the whole CatalogTable; upgrading code written before the TableChange API existed.

Understand the failure class

Background: "is deprecated and will be removed" — deprecation warnings for old API names, keywords, and options, and how to migrate before the removal release — this error's family across 29 libraries.

Related errors


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