{"record":{"id":"5f31d558f8c039fd","repo":"apache/iceberg","slug":"max-concurrent-deletes-only-works-with-fileios-tha","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/v3.5/spark/src/main/java/org/apache/iceberg/spark/procedures/ExpireSnapshotsProcedure.java","lineNumber":145,"sourceCode":"        \"max_concurrent_deletes should have value > 0, value: %s\",\n        maxConcurrentDeletes);\n\n    return modifyIcebergTable(\n        tableIdent,\n        table -> {\n          ExpireSnapshots action = actions().expireSnapshots(table);\n\n          if (olderThanMillis != null) {\n            action.expireOlderThan(olderThanMillis);\n          }\n\n          if (retainLastNum != null) {\n            action.retainLast(retainLastNum);\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, \"expire-snapshots\"));\n            }\n          }\n\n          if (snapshotIds != null) {\n            for (long snapshotId : snapshotIds) {\n              action.expireSnapshotId(snapshotId);\n            }\n          }\n\n          if (streamResult != null) {","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/procedures/ExpireSnapshotsProcedure.java#L127-L163","documentation":"When expiring snapshots, max_concurrent_deletes only tunes delete parallelism for FileIOs that delete files one-by-one. If the table's IO implements SupportsBulkOperations (e.g. S3FileIO, GCSFileIO), the parameter is ignored and this is logged.","triggerScenarios":"CALL iceberg.system.expire_snapshots(...) with max_concurrent_deletes set while table.io() instanceof SupportsBulkOperations.","commonSituations":"Users tune thread counts assuming the setting applies to S3/GCS/Azure bulk deletes; those IOs control bulk-delete parallelism via their own properties (e.g. s3.delete.batch-size, concurrency settings).","solutions":["Remove max_concurrent_deletes from the procedure call","Tune the bulk-delete parallelism via the specific FileIO's own properties (e.g. s3.delete.batch-size / filesystem concurrency settings)","Use a FileIO without bulk-delete support only if you need max_concurrent_deletes to take effect"],"exampleFix":"// before\nCALL iceberg.system.expire_snapshots(table => 'db.t', max_concurrent_deletes => 20)\n-- after\nCALL iceberg.system.expire_snapshots(table => 'db.t')  -- plus e.g. s3.delete.batch-size in table properties","handlingStrategy":"validation","validationCode":"if (table.io() instanceof org.apache.iceberg.io.SupportsBulkOperations) { /* don't pass max_concurrent_deletes */ }","typeGuard":"boolean bulkDeletes = table.io() instanceof org.apache.iceberg.io.SupportsBulkOperations;","tryCatchPattern":null,"preventionTips":["Check the table's FileIO class before setting max_concurrent_deletes","Configure bulk-delete parallelism via IO-specific properties","Read the warning's IO class name and consult its docs"],"tags":["spark","expire-snapshots","fileio","config"],"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"}