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

Apache Iceberg's FlinkCatalog does not support schema changes through Flink's legacy `alterTable(ObjectPath, CatalogTable, boolean)` API. The method compares the unresolved schema of the existing table with the requested one, and any difference throws UnsupportedOperationException. Schema evolution must go through the newer alterTable API that accepts a list of TableChange objects.

Solutions

  1. Use the TableChange-based alterTable API: `alterTable(tablePath, List.of(SchemaEvolutionUtil.addSchemaChange(...)), false)` or Flink's `ALTER TABLE ... ADD COLUMN` which maps to it.
  2. Verify that the new CatalogTable differs from the old one only in options/partition-independent properties if you must use the legacy API.
  3. Rewrite the migration code to issue explicit TableChange.addColumn/dropColumn/renameColumn updates.

Example fix

// before
catalog.alterTable(tablePath, modifiedCatalogTable, false);

// after
catalog.alterTable(tablePath,
    List.of(Change.addColumn("new_col", Types.LongType.get())),
    false);
Defensive patterns

Strategy: try-catch

Validate before calling

// compare schemas before calling legacy alterTable
if (!Objects.equals(oldCt.getUnresolvedSchema(), newCt.getUnresolvedSchema())) {
  // switch to TableChange-based alterTable instead
}

Type guard

boolean legacyApiSafe(CatalogTable a, CatalogTable b) {
  return Objects.equals(a.getUnresolvedSchema(), b.getUnresolvedSchema());
}

Try / catch

try {
  catalog.alterTable(tablePath, ct, false);
} catch (UnsupportedOperationException e) {
  // fall back to TableChange-based alterTable for schema evolution
}

Prevention

When it happens

Trigger: Calling catalog.alterTable(tablePath, newCatalogTable, false) where newCatalogTable.getUnresolvedSchema() differs from the existing table's schema (e.g. added, dropped, renamed, or retyped columns).

Common situations: Using an old Flink SQL `ALTER TABLE ... ADD/DROP COLUMN` path or a framework that still routes schema DDL through the legacy Catalog API instead of the TableChange-based API.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at flink/v2.2/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)