apache/iceberg · error · UnsupportedOperationException

AS OF is not supported for changelogs

Error message

AS OF is not supported for changelogs

What it means

Iceberg's SparkCatalog cannot perform time-travel (AS OF / VERSION AS OF) reads on a SparkChangelogTable. Changelog tables expose a stream of changes rather than snapshot-addressable state, so there is no snapshot ID to resolve a version to. The catalog deliberately rejects this with UnsupportedOperationException.

Source

Thrown at spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/SparkCatalog.java:212

      try {
        return sparkTable.copyWithSnapshotId(Long.parseLong(version));
      } catch (NumberFormatException e) {
        SnapshotRef ref = sparkTable.table().refs().get(version);
        ValidationException.check(
            ref != null,
            "Cannot find matching snapshot ID or reference name for version %s",
            version);

        if (ref.isBranch()) {
          return sparkTable.copyWithBranch(version);
        } else {
          return sparkTable.copyWithSnapshotId(ref.snapshotId());
        }
      }

    } else if (table instanceof SparkChangelogTable) {
      throw new UnsupportedOperationException("AS OF is not supported for changelogs");

    } else {
      throw new IllegalArgumentException("Unknown Spark table type: " + table.getClass().getName());
    }
  }

  @Override
  public Table loadTable(Identifier ident, long timestamp) throws NoSuchTableException {
    Table table = loadTable(ident);

    if (table instanceof SparkTable) {
      SparkTable sparkTable = (SparkTable) table;

      Preconditions.checkArgument(
          sparkTable.snapshotId() == null && sparkTable.branch() == null,
          "Cannot do time-travel based on both table identifier and AS OF");

      // convert the timestamp to milliseconds as Spark passes microseconds

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Remove the VERSION AS OF clause and read the changelog table without time travel.
  2. If historical state is needed, time-travel on the base table (catalog.db.table VERSION AS OF x) instead of its changelog view.
  3. Use snapshot reads on the base table plus explicit change computation instead of the changelog procedure.
  4. Upgrade Iceberg only if a newer release adds changelog time-travel support (currently unsupported by design).

Example fix

// before
spark.sql("SELECT * FROM prod.db.tbl_changes VERSION AS OF 3821559239432519331");
// after
spark.sql("SELECT * FROM prod.db.tbl_changes"); // no AS OF on changelog tables
Defensive patterns

Strategy: validation

Validate before calling

String sql = stmt.sqlText();
if (sql.toUpperCase(Locale.ROOT).contains("VERSION AS OF") && isChangelogTable(stmt)) {
  throw new IllegalArgumentException("AS OF is not supported for changelog tables");
}

Type guard

boolean isChangelogTable(org.apache.spark.sql.connector.catalog.Table t) {
  return t instanceof org.apache.iceberg.spark.SparkChangelogTable;
}

Try / catch

try {
  return catalog.loadTable(ident, version);
} catch (UnsupportedOperationException e) {
  if (e.getMessage().contains("AS OF is not supported")) {
    return catalog.loadTable(ident); // fall back to current state
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling Spark's time-travel syntax on a changelog view of a table, e.g. SELECT * FROM catalog.db.changelog_table VERSION AS OF 12345 (loadTable(ident, version) where the loaded table is a SparkChangelogTable).

Common situations: Developers reading change-data-capture / changelog procedures (e.g. CALL catalog.system.changelog...) and then adding AS OF or FOR VERSION AS OF clauses as they would on a normal Iceberg table.

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