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

A LOG.warn in RemoveOrphanFilesProcedure.call: identical in meaning to the expire_snapshots case — max_concurrent_deletes applies only to FileIOs lacking bulk-delete support; when the table's IO implements SupportsBulkOperations the parameter is ignored and the IO's own bulk-delete settings govern parallelism.

Source

Thrown at spark/v4.2/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 when using a bulk-capable FileIO.
  2. Adjust the IO's bulk-delete parallelism (e.g. s3.delete.batch-size for S3FileIO, or its client-level concurrency configuration).
  3. See the FileIO implementation's docs for its bulk-delete tuning options.

Example fix

// before
CALL catalog.system.remove_orphan_files(table => 'db.t', max_concurrent_deletes => 16)
// after
CALL catalog.system.remove_orphan_files(table => 'db.t')
-- tune s3.delete.batch-size / IO client concurrency instead
Defensive patterns

Strategy: validation

Validate before calling

if (table.io() instanceof SupportsBulkOperations) {
  // omit max_concurrent_deletes for remove_orphan_files
}

Type guard

boolean bulkIo = table.io() instanceof org.apache.iceberg.io.SupportsBulkOperations;

Prevention

When it happens

Trigger: CALL catalog.system.remove_orphan_files(..., max_concurrent_deletes => N) where table.io() instanceof SupportsBulkOperations (e.g. S3FileIO, GCSFileIO).

Common situations: Same as 3736: stale tuning carried over from HadoopFileIO setups; template procedure calls applied to S3/GCS-backed tables.

Related errors


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