apache/iceberg · warning

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 logs this warning when `max_concurrent_deletes` is passed but the table's FileIO implements SupportsBulkOperations. Bulk-delete IOs manage their own delete parallelism internally, so the user-supplied concurrency knob is ignored rather than honored. It is a misconfiguration notice, not a failure — orphan file removal still proceeds.

Source

Thrown at spark/v4.0/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. Remove the max_concurrent_deletes argument from the procedure call; it has no effect.
  2. Tune the IO's own bulk-delete parallelism, e.g. set 's3.delete.threads' (S3FileIO) or the equivalent property documented for your FileIO.
  3. If per-delete concurrency is truly needed, switch the table to a non-bulk FileIO such as HadoopFileIO.

Example fix

// before
CALL iceberg.system.remove_orphan_files(table => 'db.t', max_concurrent_deletes => 16)
// after
ALTER TABLE db.t SET TBLPROPERTIES ('s3.delete.threads'='16');
CALL iceberg.system.remove_orphan_files(table => 'db.t')
Defensive patterns

Strategy: validation

Validate before calling

FileIO io = table.io();
if (io instanceof SupportsBulkOperations) {
  // don't pass max_concurrent_deletes; tune the IO's own thread property instead
}

Type guard

boolean honorsMaxConcurrentDeletes = !(table.io() instanceof SupportsBulkOperations);

Prevention

When it happens

Trigger: Calling CALL iceberg.system.remove_orphan_files(...) with max_concurrent_deletes => N on a table whose io() is a bulk-capable FileIO (e.g. S3FileIO, which uses its own bulk delete thread pool).

Common situations: Copy-pasted SQL tuning advice written for HadoopFileIO applied to S3/GCS-backed tables; clusters where the catalog default FileIO changed between Iceberg versions.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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