apache/iceberg · error · 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 legacy alterTable(CatalogTable) API cannot express schema changes, so validateTableSchemaAndPartition rejects any call where the new table's unresolved schema differs from the existing table's. To change schema, callers must use the alterTable overload that accepts a list of TableChange objects.

Source

Thrown at flink/v2.1/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. Switch to the TableChange-based alterTable(objectPath, SchemaChange/TableChange list, ignoreIfNotExists) API
  2. Ensure the replacement CatalogTable has an identical unresolved schema when using the old API
  3. Reframe the operation as drop-and-recreate if a full schema rewrite is truly needed (data loss risk)

Example fix

// before
catalog.alterTable(path, tableWithNewColumns, false);
// after
catalog.alterTable(path, Arrays.asList(TableChange.addColumn("ts", DataTypes.TIMESTAMP(3))), false);
Defensive patterns

Strategy: validation

Validate before calling

if (!Objects.equals(existing.getUnresolvedSchema(), newTable.getUnresolvedSchema())) {
  throw new IllegalStateException("Use the TableChange-based alterTable API for schema changes");
}

Type guard

null

Try / catch

try { catalog.alterTable(path, newTable, false); } catch (UnsupportedOperationException e) { /* switch to TableChange-based alter */ }

Prevention

When it happens

Trigger: Calling the old alterTable(objectPath, newCatalogTable, ignoreIfNotExists) with a CatalogTable whose columns/types differ from the current table schema.

Common situations: Frameworks that materialize full table definitions and call the deprecated alterTable; users upgrading code to Flink 1.24+ style where schema changes moved to TableChange-based API.

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/5034b039ba9a4567. Report an issue: GitHub.