apache/iceberg · error · UnsupportedOperationException

Backup table name cannot be specified

Error message

Backup table name cannot be specified

What it means

MigrateTable is an interface whose backupTableName(String) default implementation throws UnsupportedOperationException. Only action implementations that actually support naming the backup table override it; on the interface itself the method is a deliberate stub. Calling it against an implementation that has not overridden it means the migration cannot create a named backup of the original table.

Source

Thrown at api/src/main/java/org/apache/iceberg/actions/MigrateTable.java:61

  MigrateTable tableProperty(String name, String value);

  /**
   * Drops the backup of the original table after a successful migration
   *
   * @return this for method chaining
   */
  default MigrateTable dropBackup() {
    throw new UnsupportedOperationException("Dropping a backup is not supported");
  }

  /**
   * Sets a table name for the backup of the original table.
   *
   * @param tableName the table name for backup
   * @return this for method chaining
   */
  default MigrateTable backupTableName(String tableName) {
    throw new UnsupportedOperationException("Backup table name cannot be specified");
  }

  /**
   * Sets the executor service to use for parallel file reading. The default is not using executor
   * service.
   *
   * @param service executor service
   * @return this for method chaining
   */
  default MigrateTable executeWith(ExecutorService service) {
    throw new UnsupportedOperationException("Setting executor service is not supported");
  }

  /**
   * Enables ignoring {@link java.io.FileNotFoundException} when listing source data files. When
   * enabled, source data files that have disappeared (for example, because a partition directory
   * was removed by concurrent cleanup) are skipped with a warning instead of failing the migration.
   * The default is to fail.

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Remove the backupTableName(...) call and let the implementation use its default backup behavior
  2. Use an implementation that supports backup names (e.g. SparkActions SparkMigrateTable) instead of the current one
  3. Check the concrete action class for an override of backupTableName before invoking it
  4. Catch UnsupportedOperationException and fall back to a plan that does not rely on the backup table

Example fix

// before
MigrateTable.Result r = actions.migrateTable(table)
    .backupTableName("table_backup")
    .execute();
// after
MigrateTable.Result r = actions.migrateTable(table)
    .execute(); // no backup name support in this implementation
Defensive patterns

Strategy: try-catch

Validate before calling

if (migrateTable.getClass().getName().endsWith("MigrateTable")) {
  throw new IllegalStateException("Implementation may not support backupTableName");
}

Try / catch

try {
  builder.backupTableName("backup");
} catch (UnsupportedOperationException e) {
  // proceed without a named backup table
}

Prevention

When it happens

Trigger: Calling migrateTable.backupTableName("backup") on an IcebergActions MigrateTable instance whose concrete implementation (e.g. a catalog or framework binding) does not override the default method.

Common situations: Users of a catalog integration (e.g. a custom ActionProvider or a non-Spark engine) that implements MigrateTable minimally assume all fluent options are supported because the Spark implementation supports them; the call fails at build time before execute() runs.

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