apache/iceberg · warning

Failed to delete {} ({})

Error message

Failed to delete {} ({})

What it means

SparkCleanupUtil deletes streaming-operation data files with retries; when a file cannot be deleted after retries (or fails repeatedly), it logs this warning with the path and cleanup context. Failures are suppressed so the main operation continues — leftover files may need manual cleanup.

Source

Thrown at spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/source/SparkCleanupUtil.java:101

   * @param files a list of files to delete
   */
  public static void deleteFiles(String context, FileIO io, List<? extends ContentFile<?>> files) {
    List<String> paths = Lists.transform(files, ContentFile::location);
    if (io instanceof SupportsBulkOperations) {
      CatalogUtil.deleteFiles(io, paths, "");
    } else {
      delete(context, io, paths);
    }
  }

  private static void delete(String context, FileIO io, List<String> paths) {
    AtomicInteger deletedFilesCount = new AtomicInteger(0);

    Tasks.foreach(paths)
        .executeWith(ThreadPools.getWorkerPool())
        .stopRetryOn(NotFoundException.class)
        .suppressFailureWhenFinished()
        .onFailure((path, exc) -> LOG.warn("Failed to delete {} ({})", path, context, exc))
        .retry(DELETE_NUM_RETRIES)
        .exponentialBackoff(
            DELETE_MIN_RETRY_WAIT_MS,
            DELETE_MAX_RETRY_WAIT_MS,
            DELETE_TOTAL_RETRY_TIME_MS,
            2 /* exponential */)
        .run(
            path -> {
              io.deleteFile(path);
              deletedFilesCount.incrementAndGet();
            });

    if (deletedFilesCount.get() < paths.size()) {
      LOG.warn("Deleted only {} of {} file(s) ({})", deletedFilesCount, paths.size(), context);
    } else {
      LOG.info("Deleted {} file(s) ({})", paths.size(), context);
    }
  }

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Check the chained exception for the root cause (permissions, throttling, missing file)
  2. If the file is already gone, the failure is benign — ignore or verify with the storage backend
  3. Fix credentials/permissions for the FileIO used by the streaming job
  4. Manually delete orphaned leftovers once the root cause is fixed
Defensive patterns

Strategy: retry

Validate before calling

// verify FileIO credentials/permissions before starting streaming jobs: io.deleteFile(existingTestPath)

Try / catch

try { io.deleteFile(path); } catch (NotFoundException e) { /* benign: already deleted */ } catch (Exception e) { /* inspect cause: permissions, throttling */ }

Prevention

When it happens

Trigger: Task attempt cleanup (deleteFiles) where io.deleteFile throws for a path — e.g. transient S3 errors, permissions, or the file already removed (NotFoundException stops retries).

Common situations: Cloud storage throttling/rate limits, concurrent jobs deleting the same files, misconfigured credentials/permissions for the cleanup executor.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


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