apache/iceberg · error · UnsupportedOperationException

does not support table invalidation

Error message

 does not support table invalidation

What it means

SparkRewriteTableCatalog.invalidateTable(ident) always throws UnsupportedOperationException because the catalog does not own table metadata (it reads from a short-lived cache); there is nothing to invalidate and cache eviction is managed by the rewrite machinery.

Source

Thrown at spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/SparkRewriteTableCatalog.java:71

      throw new NoSuchTableException(ident);
    }

    return new SparkRewriteTable(table, groupId);
  }

  @Override
  public SparkTable loadTable(Identifier ident, String version) throws NoSuchTableException {
    throw new UnsupportedOperationException(CLASS_NAME + " does not support time travel");
  }

  @Override
  public SparkTable loadTable(Identifier ident, long timestampMicros) throws NoSuchTableException {
    throw new UnsupportedOperationException(CLASS_NAME + " does not support time travel");
  }

  @Override
  public void invalidateTable(Identifier ident) {
    throw new UnsupportedOperationException(CLASS_NAME + " does not support table invalidation");
  }

  @Override
  public SparkTable createTable(Identifier ident, TableInfo tableInfo)
      throws TableAlreadyExistsException {
    throw new UnsupportedOperationException(CLASS_NAME + " does not support creating tables");
  }

  @Override
  public SparkTable alterTable(Identifier ident, TableChange... changes) {
    throw new UnsupportedOperationException(CLASS_NAME + " does not support altering tables");
  }

  @Override
  public boolean dropTable(Identifier ident) {
    throw new UnsupportedOperationException(CLASS_NAME + " does not support dropping tables");
  }

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Do not call invalidateTable on the rewrite catalog; it holds no authoritative table state.
  2. Invalidate on the real catalog (SparkCatalog.invalidateTable) if a refresh is needed.
  3. Let the rewrite procedure's SparkTableCache lifecycle manage entry freshness.

Example fix

// before
rewriteCatalog.invalidateTable(ident);
// after
sparkCatalog.invalidateTable(ident); // refresh via the real catalog
Defensive patterns

Strategy: type-guard

Validate before calling

if (catalog instanceof SparkRewriteTableCatalog) {
  throw new UnsupportedOperationException("invalidateTable not supported on rewrite catalog");
}

Type guard

boolean supportsInvalidation(CatalogPlugin c) {
  return !(c instanceof SparkRewriteTableCatalog);
}

Try / catch

try {
  catalog.invalidateTable(ident);
} catch (UnsupportedOperationException e) {
  realCatalog.invalidateTable(ident); // refresh via the authoritative catalog
}

Prevention

When it happens

Trigger: Calling invalidateTable(ident) on SparkRewriteTableCatalog directly, or Spark's session catalog cache refresh logic probing this catalog after DML.

Common situations: Framework code that invalidates cached tables generically across all registered catalogs; manual cache-busting attempts against the rewrite catalog.

Related errors


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