{"record":{"id":"1eb7ec8594a60835","repo":"prestodb/presto","slug":"failed-to-scan-changed-partitions","errorCode":null,"errorMessage":"Failed to scan changed partitions","messagePattern":"Failed to scan changed partitions","errorType":"exception","errorClass":"UncheckedIOException","httpStatus":null,"severity":"error","filePath":"presto-iceberg/src/main/java/com/facebook/presto/iceberg/IcebergAbstractMetadata.java","lineNumber":2525,"sourceCode":"                if (!APPEND.equals(operation) && !REPLACE.equals(operation)) {\n                    return Optional.empty();\n                }\n            }\n        }\n\n        Set<StructLike> partitions = new HashSet<>();\n\n        IncrementalAppendScan scan = icebergTable.newIncrementalAppendScan()\n                .fromSnapshotExclusive(fromSnapshotId)\n                .toSnapshot(toSnapshotId);\n\n        try (CloseableIterable<FileScanTask> tasks = scan.planFiles()) {\n            for (FileScanTask task : tasks) {\n                partitions.add(task.file().partition());\n            }\n        }\n        catch (IOException e) {\n            throw new UncheckedIOException(\"Failed to scan changed partitions\", e);\n        }\n\n        return Optional.of(ImmutableSet.copyOf(partitions));\n    }\n\n    private List<TupleDomain<String>> convertPartitionsToConstraints(\n            ConnectorSession session,\n            Table icebergTable,\n            PartitionSpec spec,\n            Set<StructLike> partitions)\n    {\n        List<TupleDomain<String>> constraints = new ArrayList<>();\n\n        for (StructLike partition : partitions) {\n            Map<String, Domain> domainMap = new HashMap<>();\n\n            for (int i = 0; i < spec.fields().size(); i++) {\n                PartitionField field = spec.fields().get(i);","sourceCodeStart":2507,"sourceCodeEnd":2543,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-iceberg/src/main/java/com/facebook/presto/iceberg/IcebergAbstractMetadata.java#L2507-L2543","documentation":"This wraps an IOException raised while planning file scan tasks of an Iceberg table to collect changed partitions during materialized view incremental refresh. The failure is environmental/IO related, not logical — Presto could not read the table's manifest/plan files.","triggerScenarios":"Calling incremental refresh path where planFiles() on a table scan throws IOException — e.g. missing manifest files, permission errors, or storage (HDFS/S3) unavailability while reading manifests.","commonSituations":"Underlying manifest/data files deleted by compaction or expiry jobs, metastore/HDFS outages, S3 throttling or credentials issues, corrupted table metadata.","solutions":["Check the wrapped IOException cause for the root storage error and fix access/permissions or network to the object store/HDFS.","Verify table metadata and manifest files are intact; repair or re-register the table if files were deleted.","Retry refresh after storage issues are resolved; run a full REFRESH MATERIALIZED VIEW as a fallback."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// pre-check storage accessibility via a lightweight metadata read\nSELECT 1 FROM catalog.schema.\"base$partitions\" LIMIT 1;","typeGuard":null,"tryCatchPattern":"try {\n    refreshMv();\n} catch (PrestoException e) {\n    if (e.getCause() instanceof UncheckedIOException || e.getMessage().contains(\"Failed to scan changed partitions\")) {\n        retryWithBackoff(refreshMv, 3);\n    } else throw e;\n}","preventionTips":["Ensure storage (HDFS/S3) connectivity and credentials before refresh jobs","Do not delete manifest files out from under running refreshes","Add retries with backoff around refresh in schedulers"],"tags":["iceberg","io","file-scan","refresh"],"backgroundTag":"io-exception-table-scan","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}