apache/iceberg · error · UnsupportedOperationException

Cannot append to a %s table

Error message

Cannot append to a %s table

What it means

Iceberg throws this UnsupportedOperationException when newAppend() is called on a read-only table. Appending data files produces a new snapshot, a write operation that BaseReadOnlyTable subclasses (metadata tables, read-only views) never permit. The descriptor names the read-only table kind.

Source

Thrown at core/src/main/java/org/apache/iceberg/BaseReadOnlyTable.java:61

    throw new UnsupportedOperationException(
        "Cannot update the properties of a " + descriptor + " table");
  }

  @Override
  public ReplaceSortOrder replaceSortOrder() {
    throw new UnsupportedOperationException(
        "Cannot update the sort order of a " + descriptor + " table");
  }

  @Override
  public UpdateLocation updateLocation() {
    throw new UnsupportedOperationException(
        "Cannot update the location of a " + descriptor + " table");
  }

  @Override
  public AppendFiles newAppend() {
    throw new UnsupportedOperationException("Cannot append to a " + descriptor + " table");
  }

  @Override
  public RewriteFiles newRewrite() {
    throw new UnsupportedOperationException("Cannot rewrite in a " + descriptor + " table");
  }

  @Override
  public RewriteManifests rewriteManifests() {
    throw new UnsupportedOperationException(
        "Cannot rewrite manifests in a " + descriptor + " table");
  }

  @Override
  public OverwriteFiles newOverwrite() {
    throw new UnsupportedOperationException("Cannot overwrite in a " + descriptor + " table");
  }

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Append to the writable data table loaded from the catalog, not the metadata-table handle.
  2. Verify which Table instance the writer holds before calling newAppend().
  3. If the intent was writing to a view's underlying table, load the base table explicitly.

Example fix

// before
table.snapshots().newAppend().appendFile(dataFile).commit();

// after
Table dataTable = catalog.loadTable(TableIdentifier.of("db", "tbl"));
dataTable.newAppend().appendFile(dataFile).commit();
Defensive patterns

Strategy: try-catch

Validate before calling

if (isMetadataTableName(table.name())) { throw new IllegalArgumentException("Cannot append to metadata table " + table.name()); }

Type guard

boolean canAppend = !(table instanceof BaseReadOnlyTable); // ensure handle came from Catalog.loadTable

Try / catch

try {
  table.newAppend().appendFile(file).commit();
} catch (UnsupportedOperationException e) {
  log.error("Cannot append to read-only table {}", table.name(), e);
}

Prevention

When it happens

Trigger: Calling table.newAppend().appendFile(...).commit() on a metadata table (e.g. table.snapshots()) or any other BaseReadOnlyTable subclass.

Common situations: Ingestion pipelines that resolve a Table object by name and accidentally bind a metadata-table reference, or generic writer code applied to read-only views.

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