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

  1. Retry the DELETE — the fallback delete path still works
  2. Inspect the wrapped IOException cause for the underlying FileIO issue
  3. 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

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


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)