apache/iceberg · error · UnsupportedOperationException

cleanExpiredMetadata is not supported

Error message

cleanExpiredMetadata is not supported

What it means

ExpireSnapshots is an action interface whose fluent option cleanExpiredMetadata(boolean) — controlling removal of unused partition specs, schemas, and other metadata during expiration — is a default that throws UnsupportedOperationException. It indicates the action implementation does not support metadata cleanup during snapshot expiration.

Source

Thrown at api/src/main/java/org/apache/iceberg/actions/ExpireSnapshots.java:112

   *
   * @param executorService the service to use
   * @return this for method chaining
   */
  ExpireSnapshots executeDeleteWith(ExecutorService executorService);

  /**
   * Expires unused table metadata such as partition specs and schemas.
   *
   * <p>Metadata such as partition specs or schemas that are no longer referenced by snapshots will
   * be removed.
   *
   * <p>Identical to {@link org.apache.iceberg.ExpireSnapshots#cleanExpiredMetadata(boolean)}
   *
   * @param clean remove unused partition specs, schemas, or other metadata when true
   * @return this for method chaining
   */
  default ExpireSnapshots cleanExpiredMetadata(boolean clean) {
    throw new UnsupportedOperationException("cleanExpiredMetadata is not supported");
  }

  /** The action result that contains a summary of the execution. */
  interface Result {
    /** Returns the number of deleted data files. */
    long deletedDataFilesCount();

    /** Returns the number of deleted equality delete files. */
    long deletedEqualityDeleteFilesCount();

    /** Returns the number of deleted position delete files. */
    long deletedPositionDeleteFilesCount();

    /** Returns the number of deleted manifests. */
    long deletedManifestsCount();

    /** Returns the number of deleted manifest lists. */
    long deletedManifestListsCount();

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Upgrade the engine integration module to a version whose ExpireSnapshots implementation supports cleanExpiredMetadata.
  2. Remove the cleanExpiredMetadata call if metadata cleanup is not required (snapshots-only expiration still works).
  3. Override cleanExpiredMetadata in a custom ExpireSnapshots implementation.

Example fix

// before
ExpireSnapshots a = SparkActions.get().expireSnapshots(table).cleanExpiredMetadata(true); // throws on old impl
// after (upgrade iceberg-spark, or drop the call)
ExpireSnapshots a = SparkActions.get().expireSnapshots(table);
Defensive patterns

Strategy: try-catch

Validate before calling

boolean ok = Arrays.stream(expire.getClass().getMethods()).anyMatch(m -> "cleanExpiredMetadata".equals(m.getName()) && m.getDeclaringClass() != ExpireSnapshots.class);

Type guard

boolean implemented = expire.getClass() != ExpireSnapshots.class;

Try / catch

try { expire = expire.cleanExpiredMetadata(true); } catch (UnsupportedOperationException e) { LOG.warn("Metadata cleanup unsupported; expiring snapshots only"); }

Prevention

When it happens

Trigger: Calling expireSnapshots(...).cleanExpiredMetadata(true) on an action implementation that has not overridden the method, e.g., an older engine runtime or custom action.

Common situations: Attempting full metadata GC (specs/schemas cleanup) with an engine integration that predates the option; following current examples against an older Iceberg dependency.

Related errors


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