{"record":{"id":"f62c7a5a3f5c368a","repo":"apache/iceberg","slug":"cannot-scan-table-as-of-time-s-configured-for-in","errorCode":null,"errorMessage":"Cannot scan table as of time %s: configured for incremental data in snapshots (%s, %s]","messagePattern":"Cannot scan table as of time (.+?): configured for incremental data in snapshots \\((.+?), (.+?)\\]","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/IncrementalDataTableScan.java","lineNumber":41,"sourceCode":"import org.apache.iceberg.events.IncrementalScanEvent;\nimport org.apache.iceberg.events.Listeners;\nimport org.apache.iceberg.io.CloseableIterable;\nimport org.apache.iceberg.relocated.com.google.common.base.Preconditions;\nimport org.apache.iceberg.relocated.com.google.common.collect.FluentIterable;\nimport org.apache.iceberg.relocated.com.google.common.collect.Iterables;\nimport org.apache.iceberg.relocated.com.google.common.collect.Lists;\nimport org.apache.iceberg.relocated.com.google.common.collect.Sets;\nimport org.apache.iceberg.util.SnapshotUtil;\n\nclass IncrementalDataTableScan extends DataTableScan {\n  IncrementalDataTableScan(Table table, Schema schema, TableScanContext context) {\n    super(table, schema, context.useSnapshotId(null));\n    validateSnapshotIds(table, context.fromSnapshotId(), context.toSnapshotId());\n  }\n\n  @Override\n  public TableScan asOfTime(long timestampMillis) {\n    throw new UnsupportedOperationException(\n        String.format(\n            \"Cannot scan table as of time %s: configured for incremental data in snapshots (%s, %s]\",\n            timestampMillis, context().fromSnapshotId(), context().toSnapshotId()));\n  }\n\n  @Override\n  public TableScan useRef(String ref) {\n    throw new UnsupportedOperationException(\n        String.format(\n            \"Cannot scan table using ref %s: configured for incremental data in snapshots (%s, %s]\",\n            ref, context().fromSnapshotId(), context().toSnapshotId()));\n  }\n\n  @Override\n  public TableScan useSnapshot(long scanSnapshotId) {\n    throw new UnsupportedOperationException(\n        String.format(\n            \"Cannot scan table using scan snapshot id %s: configured for incremental data in snapshots (%s, %s]\",","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/IncrementalDataTableScan.java#L23-L59","documentation":"IncrementalDataTableScan scans appended data between two snapshot IDs. asOfTime() re-pins the scan to a point-in-time snapshot, which is meaningless for an incremental (fromSnapshot, toSnapshot) scan, so it unconditionally throws UnsupportedOperationException with the scan's configured snapshot range in the message.","triggerScenarios":"Calling table.incrementalScan(...).asOfTime(timestampMillis) on the TableScan returned by an incremental scan (IncrementalAppendScan / IncrementalChangelogScan result).","commonSituations":"Frameworks that generically call asOfTime on every scan (time-travel helpers); reusing scan-configuration code paths written for normal TableScan objects on incremental scans; Spark/Flink options like 'as-of-timestamp' applied to an incremental read.","solutions":["Remove the asOfTime call for incremental scans; time travel does not apply - choose fromSnapshot/toSnapshot instead.","Convert to a normal scan (table.scan()) if you actually want point-in-time reads, or use SnapshotUtil.snapshotIdAsOfTime to resolve a snapshot ID and pass it as toSnapshotId.","Wrap the call in a check (scan instanceof IncrementalDataTableScan) to skip asOfTime for incremental scans."],"exampleFix":"// before\nTableScan scan = table.incrementalScan(startId, endId).asOfTime(ts);\n// after\nTableScan scan = table.incrementalScan(startId, endId); // configure via fromSnapshot/toSnapshot only","handlingStrategy":"type-guard","validationCode":"// before configuring:\nif (scan instanceof org.apache.iceberg.IncrementalDataTableScan) {\n  throw new IllegalArgumentException(\"asOfTime is not supported for incremental scans\");\n}","typeGuard":"boolean supportsTimeTravel(TableScan scan) {\n  return !(scan instanceof org.apache.iceberg.IncrementalDataTableScan);\n}","tryCatchPattern":"try {\n  scan.asOfTime(ts);\n} catch (UnsupportedOperationException e) {\n  // fall back to a range configuration or a normal scan\n  scan = table.scan().asOfTime(ts);\n}","preventionTips":["Never apply generic scan options (as-of-timestamp, branch, snapshot-id) uniformly to incremental scans.","Resolve point-in-time snapshot IDs with SnapshotUtil and use toSnapshot for incremental reads."],"tags":["incremental-scan","time-travel","unsupported-operation"],"backgroundTag":"unsupported-operation","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}