apache/iceberg · warning
Failed to close task iterable
Error message
Failed to close task iterable
What it means
A WARN logged by SparkTable.canDeleteUsingMetadata when an IOException occurs while closing the CloseableIterable of task/file contexts used to evaluate whether a DELETE can be satisfied by metadata only (partition and metrics evaluation). The method returns false, so Spark falls back to a non-metadata (row-level or rewrite) delete — correctness is preserved, only the fast path is lost.
Solutions
- Retry the DELETE — the fallback delete path still works
- Inspect the wrapped IOException cause for the underlying FileIO issue
- Verify storage connectivity/credentials used by the table's FileIO
Defensive patterns
Strategy: retry
Try / catch
try {
boolean ok = sparkTable.canDeleteWhere(predicates);
if (!ok) { /* fall back to row-level delete */ }
} catch (Exception e) {
// fall back to rewrite/row-level delete path
} Prevention
- Ensure stable connectivity to the table's object storage
- Check FileIO configuration (endpoints, credentials) before DELETE workloads
- Retry metadata-only deletes once on transient IOExceptions
When it happens
Trigger: canDeleteWhere -> canDeleteUsingMetadata opens a task iterable over table files; closing it throws IOException (underlying FileIO/manifest read error), or an earlier read inside the try-with-resources fails.
Common situations: Object-store transient errors while reading manifests/metrics; FileIO misconfiguration; network interruptions during scan planning.
Related errors
- Failed reading offset from
- Failed to close changelog scan:
- Failed to close scan: " + scan
- Failed to close task iterable
- Failed to close task iterable
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/4339b7b4a3442c30.
Report an issue: GitHub.
Appendix: source
Thrown at spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/source/SparkTable.java:258
try (CloseableIterable<FileScanTask> tasks = scan.planFiles()) {
Map<Integer, Evaluator> evaluators = Maps.newHashMap();
StrictMetricsEvaluator metricsEvaluator = new StrictMetricsEvaluator(schema, deleteExpr);
return Iterables.all(
tasks,
task -> {
DataFile file = task.file();
PartitionSpec spec = task.spec();
Evaluator evaluator =
evaluators.computeIfAbsent(
spec.specId(),
specId ->
new Evaluator(
spec.partitionType(), Projections.strict(spec).project(deleteExpr)));
return evaluator.eval(file.partition()) || metricsEvaluator.eval(file);
});
} catch (IOException ioe) {
LOG.warn("Failed to close task iterable", ioe);
return false;
}
}
@Override
public void deleteWhere(Predicate[] predicates) {
Expression deleteExpr = SparkV2Filters.convert(predicates);
if (deleteExpr == Expressions.alwaysFalse()) {
LOG.info("Skipping the delete operation as the condition is always false");
return;
}
DeleteFiles deleteFiles =
table()
.newDelete()
.set("spark.app.id", spark().sparkContext().applicationId())
.deleteFromRowFilter(deleteExpr);View on GitHub (pinned to 86d9c8fc54)