apache/iceberg · error · UnsupportedOperationException

Cannot select snapshot in table: ${tableType}

Error message

Cannot select snapshot in table: ${tableType}

What it means

BaseAllMetadataTableScan.useSnapshot() always throws UnsupportedOperationException because 'all_*' metadata tables (all_data_files, all_manifests, all_delete_files, all_entries) aggregate across all snapshots, so selecting a single snapshot is meaningless. Time-travel/ref-selection APIs are intentionally unsupported on these scans.

Source

Thrown at core/src/main/java/org/apache/iceberg/BaseAllMetadataTableScan.java:49

import org.apache.iceberg.util.ParallelIterable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

abstract class BaseAllMetadataTableScan extends BaseMetadataTableScan {
  private static final Logger LOG = LoggerFactory.getLogger(BaseAllMetadataTableScan.class);

  BaseAllMetadataTableScan(Table table, Schema schema, MetadataTableType tableType) {
    super(table, schema, tableType);
  }

  BaseAllMetadataTableScan(
      Table table, Schema schema, MetadataTableType tableType, TableScanContext context) {
    super(table, schema, tableType, context);
  }

  @Override
  public TableScan useSnapshot(long scanSnapshotId) {
    throw new UnsupportedOperationException("Cannot select snapshot in table: " + tableType());
  }

  @Override
  public TableScan useRef(String ref) {
    throw new UnsupportedOperationException("Cannot select ref in table: " + tableType());
  }

  @Override
  public TableScan asOfTime(long timestampMillis) {
    throw new UnsupportedOperationException("Cannot select snapshot in table: " + tableType());
  }

  @Override
  public CloseableIterable<FileScanTask> planFiles() {
    String metadataTableName = table().name() + "." + tableType().name().toLowerCase(Locale.ROOT);
    LOG.info(
        "Scanning metadata table {} with filter {}.",
        metadataTableName,

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Remove the useSnapshot call when scanning all_* metadata tables
  2. Scan the regular (non-all) metadata table such as the files/entries table if per-snapshot data is needed
  3. Restrict snapshot selection in generic query planners to non-metadata tables (check tableType before calling useSnapshot)

Example fix

// before
scan = table.scan("all_data_files").useSnapshot(snapshotId);
// after
scan = table.scan("all_data_files"); // all_* tables span all snapshots; no time travel
Defensive patterns

Strategy: validation

Validate before calling

boolean isAllMetadataTable = tableName.contains(".all_");
if (!isAllMetadataTable) {
  scan = scan.useSnapshot(snapshotId);
}

Type guard

null

Try / catch

try { scan.useSnapshot(id); } catch (UnsupportedOperationException e) { /* scanning all_* table; skip snapshot selection */ }

Prevention

When it happens

Trigger: Calling tableScan.useSnapshot(id) on a scan of an all_* metadata table, e.g. table.scan("all_data_files").useSnapshot(123L).

Common situations: Reusing generic scan-building code that applies time travel to every table, including metadata tables; Spark SQL queries with FOR VERSION AS OF against all_* tables.

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/0cfd12e7d373e1cb. Report an issue: GitHub.