apache/iceberg · info

max_concurrent_deletes only works with FileIOs that do not s

Error message

max_concurrent_deletes only works with FileIOs that do not support bulk deletes. This table is currently using {} which supports bulk deletes so the parameter will be ignored. See that IO's documentation to learn how to adjust parallelism for that particular IO's bulk delete.

What it means

RemoveOrphanFilesProcedure warns that max_concurrent_deletes only controls delete parallelism for FileIOs without bulk delete support. When the table's IO implements SupportsBulkOperations, deletes go through the IO's bulk API and the option is ignored.

Source

Thrown at spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/procedures/RemoveOrphanFilesProcedure.java:176

          if (olderThanMillis != null) {
            boolean isTesting = Boolean.parseBoolean(spark().conf().get("spark.testing", "false"));
            if (!isTesting) {
              validateInterval(olderThanMillis);
            }
            action.olderThan(olderThanMillis);
          }

          if (location != null) {
            action.location(location);
          }

          if (dryRun) {
            action.deleteWith(file -> {});
          }

          if (maxConcurrentDeletes != null) {
            if (table.io() instanceof SupportsBulkOperations) {
              LOG.warn(
                  "max_concurrent_deletes only works with FileIOs that do not support bulk deletes. This "
                      + "table is currently using {} which supports bulk deletes so the parameter will be ignored. "
                      + "See that IO's documentation to learn how to adjust parallelism for that particular "
                      + "IO's bulk delete.",
                  table.io().getClass().getName());
            } else {

              action.executeDeleteWith(executorService(maxConcurrentDeletes, "remove-orphans"));
            }
          }

          if (fileListView != null) {
            action.compareToFileList(spark().table(fileListView));
          }

          action.equalSchemes(equalSchemes);
          action.equalAuthorities(equalAuthorities);

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Drop max_concurrent_deletes for bulk-capable IOs and tune the IO's bulk delete configuration instead
  2. Only pass max_concurrent_deletes for IOs without SupportsBulkOperations
  3. Consult the specific FileIO's docs for its bulk-delete parallelism properties

Example fix

// before
CALL iceberg.system.remove_orphan_files(table => 'db.t', max_concurrent_deletes => 8)
// after
CALL iceberg.system.remove_orphan_files(table => 'db.t')  -- tune S3FileIO bulk delete via IO properties
Defensive patterns

Strategy: validation

Validate before calling

if (maxConcurrentDeletes != null && table.io() instanceof SupportsBulkOperations) {
  // drop the option; tune the IO's bulk delete instead
}

Type guard

boolean bulkSupported = table.io() instanceof SupportsBulkOperations;

Prevention

When it happens

Trigger: Calling CALL iceberg.system.remove_orphan_files(...) with max_concurrent_deletes set when table.io() instanceof SupportsBulkOperations.

Common situations: S3FileIO/GCSFileIO tables where users copied HadoopFileIO-era tuning parameters; scripts parameterized uniformly across tables with different IOs.

Related errors


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