apache/iceberg · error · UnsupportedOperationException

Setting executor service is not supported

Error message

Setting executor service is not supported

What it means

MigrateTable.executeWith(ExecutorService) is a default interface method that throws UnsupportedOperationException. Implementations that cannot accept a caller-provided executor service keep the default stub, so requesting custom parallelism on such an implementation is rejected.

Source

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

  /**
   * 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.
   *
   * @return this for method chaining
   */
  default MigrateTable ignoreMissingFiles() {
    throw new UnsupportedOperationException("Ignoring missing files is not supported");
  }

  /** The action result that contains a summary of the execution. */
  interface Result {
    /** Returns the number of migrated data files. */
    long migratedDataFilesCount();

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Drop the executeWith(...) call and let the implementation use its default execution model
  2. Switch to an implementation that supports custom executors (e.g. SparkMigrateTable)
  3. Tune parallelism via implementation-supported properties instead of a supplied ExecutorService
  4. Guard the call with an instanceof/capability check before configuring the executor

Example fix

// before
MigrateTable.Result r = actions.migrateTable(table)
    .executeWith(executorService)
    .execute();
// after
MigrateTable.Result r = actions.migrateTable(table)
    .execute(); // default execution
Defensive patterns

Strategy: try-catch

Try / catch

try {
  builder.executeWith(executorService);
} catch (UnsupportedOperationException e) {
  // fall back to default single-threaded execution
}

Prevention

When it happens

Trigger: Calling migrateTable.executeWith(executorService) on an implementation that has not overridden the default method, typically to parallelize manifest reading during migration.

Common situations: Developers copy tuning code written for SparkActions' MigrateTable onto a different engine or custom implementation that runs the migration single-threaded; the executor customization is unsupported there.

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