apache/iceberg · error · UnsupportedOperationException

Cannot scan table as of time %s: configured for incremental

Error message

Cannot scan table as of time %s: configured for incremental data in snapshots (%s, %s]

What it means

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.

Source

Thrown at core/src/main/java/org/apache/iceberg/IncrementalDataTableScan.java:41

import org.apache.iceberg.events.IncrementalScanEvent;
import org.apache.iceberg.events.Listeners;
import org.apache.iceberg.io.CloseableIterable;
import org.apache.iceberg.relocated.com.google.common.base.Preconditions;
import org.apache.iceberg.relocated.com.google.common.collect.FluentIterable;
import org.apache.iceberg.relocated.com.google.common.collect.Iterables;
import org.apache.iceberg.relocated.com.google.common.collect.Lists;
import org.apache.iceberg.relocated.com.google.common.collect.Sets;
import org.apache.iceberg.util.SnapshotUtil;

class IncrementalDataTableScan extends DataTableScan {
  IncrementalDataTableScan(Table table, Schema schema, TableScanContext context) {
    super(table, schema, context.useSnapshotId(null));
    validateSnapshotIds(table, context.fromSnapshotId(), context.toSnapshotId());
  }

  @Override
  public TableScan asOfTime(long timestampMillis) {
    throw new UnsupportedOperationException(
        String.format(
            "Cannot scan table as of time %s: configured for incremental data in snapshots (%s, %s]",
            timestampMillis, context().fromSnapshotId(), context().toSnapshotId()));
  }

  @Override
  public TableScan useRef(String ref) {
    throw new UnsupportedOperationException(
        String.format(
            "Cannot scan table using ref %s: configured for incremental data in snapshots (%s, %s]",
            ref, context().fromSnapshotId(), context().toSnapshotId()));
  }

  @Override
  public TableScan useSnapshot(long scanSnapshotId) {
    throw new UnsupportedOperationException(
        String.format(
            "Cannot scan table using scan snapshot id %s: configured for incremental data in snapshots (%s, %s]",

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Remove the asOfTime call for incremental scans; time travel does not apply - choose fromSnapshot/toSnapshot instead.
  2. 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.
  3. Wrap the call in a check (scan instanceof IncrementalDataTableScan) to skip asOfTime for incremental scans.

Example fix

// before
TableScan scan = table.incrementalScan(startId, endId).asOfTime(ts);
// after
TableScan scan = table.incrementalScan(startId, endId); // configure via fromSnapshot/toSnapshot only
Defensive patterns

Strategy: type-guard

Validate before calling

// before configuring:
if (scan instanceof org.apache.iceberg.IncrementalDataTableScan) {
  throw new IllegalArgumentException("asOfTime is not supported for incremental scans");
}

Type guard

boolean supportsTimeTravel(TableScan scan) {
  return !(scan instanceof org.apache.iceberg.IncrementalDataTableScan);
}

Try / catch

try {
  scan.asOfTime(ts);
} catch (UnsupportedOperationException e) {
  // fall back to a range configuration or a normal scan
  scan = table.scan().asOfTime(ts);
}

Prevention

When it happens

Trigger: Calling table.incrementalScan(...).asOfTime(timestampMillis) on the TableScan returned by an incremental scan (IncrementalAppendScan / IncrementalChangelogScan result).

Common situations: 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.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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