{"record":{"id":"059d312f0316f63c","repo":"apache/iceberg","slug":"max-concurrent-deletes-only-works-with-fileios-tha-059d31","errorCode":null,"errorMessage":"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.","messagePattern":"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\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/procedures/RemoveOrphanFilesProcedure.java","lineNumber":176,"sourceCode":"          if (olderThanMillis != null) {\n            boolean isTesting = Boolean.parseBoolean(spark().conf().get(\"spark.testing\", \"false\"));\n            if (!isTesting) {\n              validateInterval(olderThanMillis);\n            }\n            action.olderThan(olderThanMillis);\n          }\n\n          if (location != null) {\n            action.location(location);\n          }\n\n          if (dryRun) {\n            action.deleteWith(file -> {});\n          }\n\n          if (maxConcurrentDeletes != null) {\n            if (table.io() instanceof SupportsBulkOperations) {\n              LOG.warn(\n                  \"max_concurrent_deletes only works with FileIOs that do not support bulk deletes. This \"\n                      + \"table is currently using {} which supports bulk deletes so the parameter will be ignored. \"\n                      + \"See that IO's documentation to learn how to adjust parallelism for that particular \"\n                      + \"IO's bulk delete.\",\n                  table.io().getClass().getName());\n            } else {\n\n              action.executeDeleteWith(executorService(maxConcurrentDeletes, \"remove-orphans\"));\n            }\n          }\n\n          if (fileListView != null) {\n            action.compareToFileList(spark().table(fileListView));\n          }\n\n          action.equalSchemes(equalSchemes);\n          action.equalAuthorities(equalAuthorities);\n","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/procedures/RemoveOrphanFilesProcedure.java#L158-L194","documentation":"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.","triggerScenarios":"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).","commonSituations":"Copy-pasted SQL tuning advice written for HadoopFileIO applied to S3/GCS-backed tables; clusters where the catalog default FileIO changed between Iceberg versions.","solutions":["Remove the max_concurrent_deletes argument from the procedure call; it has no effect.","Tune the IO's own bulk-delete parallelism, e.g. set 's3.delete.threads' (S3FileIO) or the equivalent property documented for your FileIO.","If per-delete concurrency is truly needed, switch the table to a non-bulk FileIO such as HadoopFileIO."],"exampleFix":"// before\nCALL iceberg.system.remove_orphan_files(table => 'db.t', max_concurrent_deletes => 16)\n// after\nALTER TABLE db.t SET TBLPROPERTIES ('s3.delete.threads'='16');\nCALL iceberg.system.remove_orphan_files(table => 'db.t')","handlingStrategy":"validation","validationCode":"FileIO io = table.io();\nif (io instanceof SupportsBulkOperations) {\n  // don't pass max_concurrent_deletes; tune the IO's own thread property instead\n}","typeGuard":"boolean honorsMaxConcurrentDeletes = !(table.io() instanceof SupportsBulkOperations);","tryCatchPattern":null,"preventionTips":["Check the table's FileIO class before setting delete concurrency options.","Use IO-specific properties (e.g. s3.delete.threads) for bulk-delete parallelism.","Log/treat ignored parameters as config drift in job validation."],"tags":["spark","configuration","fileio","ignored-parameter"],"backgroundTag":"conflicting-config-options","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T21:17:11.552Z"}