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
- Drop the executeWith(...) call and let the implementation use its default execution model
- Switch to an implementation that supports custom executors (e.g. SparkMigrateTable)
- Tune parallelism via implementation-supported properties instead of a supplied ExecutorService
- 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
- Only set a custom ExecutorService on implementations documented to support it
- Never assume Spark-specific tuning options exist on other engine bindings
- Wrap option chaining in helpers that degrade gracefully
- Review the interface's default method bodies to see which options are stubs
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
- Backup table name cannot be specified
- Ignoring missing files is not supported
- this.getClass().getName() + " doesn't implement sortBy(List<
- This implementation does not support providing an ExecutorSe
- Setting executor service is not supported
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/5e2f8d372624b491.
Report an issue: GitHub.