prestodb/presto · critical · UncheckedIOException

Failed to scan table file tasks

Error message

Failed to scan table file tasks

What it means

IcebergUtil scans a table's FileScanTasks (via Iceberg's TableScan tasks) to group files by partition for the optimize/rewrite planner. Reading the tasks performs I/O over manifest/data file metadata; if that I/O throws IOException, it is wrapped in UncheckedIOException with the message 'Failed to scan table file tasks' so it can propagate from the stream/loop.

Source

Thrown at presto-iceberg/src/main/java/com/facebook/presto/iceberg/IcebergUtil.java:1894

        }

        int minInputFiles = parseMinInputFiles(options);
        if (minInputFiles <= 1) {
            return tasks;
        }

        // Group files by partition
        Map<String, List<FileScanTask>> partitionGroups = new HashMap<>();
        Map<String, Set<String>> partitionFilePathGroups = new HashMap<>();
        try (CloseableIterable<FileScanTask> autoCloseTasks = tasks) {
            for (FileScanTask task : autoCloseTasks) {
                String partitionKey = getPartitionKey(task);
                partitionGroups.computeIfAbsent(partitionKey, k -> new ArrayList<>()).add(task);
                partitionFilePathGroups.computeIfAbsent(partitionKey, k -> new HashSet<>()).add(task.file().location());
            }
        }
        catch (IOException e) {
            throw new UncheckedIOException("Failed to scan table file tasks", e);
        }

        // Collect tasks from partitions that meet the threshold
        List<FileScanTask> filteredTasks = new ArrayList<>();
        for (String partitionKey : partitionFilePathGroups.keySet()) {
            if (partitionFilePathGroups.get(partitionKey).size() >= minInputFiles) {
                filteredTasks.addAll(partitionGroups.get(partitionKey));
            }
        }
        return CloseableIterable.withNoopClose(filteredTasks);
    }

    /**
     * Filters files by individual file criteria using OR logic.
     * Selects files that are too small (< min-file-size-bytes) OR too large (> max-file-size-bytes).
     * If rewrite-all is true, skips filtering and returns all tasks.
     *
     * @param tasks all available tasks

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Check storage connectivity/credentials (S3/HDFS/GCS access) and retry the operation once the backend is reachable.
  2. Verify that all files referenced by the table's manifests exist — restore accidentally deleted files or run metadata repair.
  3. Inspect the wrapped cause (getCause()) from the UncheckedIOException for the precise storage error (403, FileNotFoundException, timeout).
  4. If files are orphaned/dangling in manifests, expire snapshots or use Iceberg remove-orphan-files/repair tooling to realign metadata with storage.

Example fix

// before
try { scanTasks = table.newScan().planTasks(); ... }
catch (UncheckedIOException e) { LOG.error("scan failed", e); } // cause hidden
// after
try { scanTasks = table.newScan().planTasks(); ... }
catch (UncheckedIOException e) {
  LOG.error("Failed to scan table file tasks: {}", e.getCause().getMessage(), e.getCause());
  throw e; // or retry against recovered storage
}
Defensive patterns

Strategy: try-catch

Validate before calling

// preflight: confirm table location and a sample file are reachable before scanning
boolean reachable = fs.exists(new Path(tableLocation, "metadata"));

Try / catch

try {
    scanTableFileTasks(table);
} catch (UncheckedIOException e) {
    IOException cause = e.getCause();
    if (cause instanceof FileNotFoundException) {
        // missing manifest/data file: repair metadata or restore object
    } else {
        // storage connectivity/permission issue: retry with backoff
    }
    throw e;
}

Prevention

When it happens

Trigger: Invoking table scan tasks during optimize when underlying storage is unavailable or unreadable: missing/deleted manifest or data files listed in metadata, HDFS/S3 connectivity failures, permission errors, or corrupt manifest avro files.

Common situations: Objects deleted from object storage out-of-band (retention job removing files still referenced by manifests); expired credentials to S3/GCS; HDFS NameNode unreachable; network partition mid-scan; manually cleaned-up table locations.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/1acc2c112b8ee749. Report an issue: GitHub.