apache/iceberg · error · ValidationException

Cannot apply unknown WAP ID '%s'

Error message

Cannot apply unknown WAP ID '%s'

What it means

PublishChangesProcedure looks up a staged snapshot whose write.wap.id matches the given id. ValidationException is thrown when no snapshot in the table's history carries that WAP ID, so there is nothing to publish.

Source

Thrown at spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/procedures/PublishChangesProcedure.java:112

    return modifyIcebergTable(
        tableIdent,
        table -> {
          Snapshot matchingSnap = null;
          for (Snapshot snap : table.snapshots()) {
            if (wapId.equals(WapUtil.stagedWapId(snap))) {
              if (matchingSnap != null) {
                throw new ValidationException(
                    "Cannot apply non-unique WAP ID. Found multiple snapshots with WAP ID '%s'",
                    wapId);
              } else {
                matchingSnap = snap;
              }
            }
          }

          if (matchingSnap == null) {
            throw new ValidationException("Cannot apply unknown WAP ID '%s'", wapId);
          }

          long wapSnapshotId = matchingSnap.snapshotId();
          table.manageSnapshots().cherrypick(wapSnapshotId).commit();
          Snapshot currentSnapshot = table.currentSnapshot();
          InternalRow outputRow = newInternalRow(wapSnapshotId, currentSnapshot.snapshotId());
          return asScanIterator(OUTPUT_TYPE, outputRow);
        });
  }

  @Override
  public String name() {
    return NAME;
  }

  @Override
  public String description() {
    return "ApplyWapChangesProcedure";

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Confirm the staged write ran with spark.wap.id set to the same value, and that the job committed
  2. Inspect table.snapshots (or the snapshots metadata table) to find existing wap IDs: SELECT * FROM cat.db.t.snapshots
  3. Use the correct table identifier in the procedure call
  4. If the snapshot was already published, no action is needed — publish_changes is not idempotent

Example fix

// before
spark-submit ... # job without spark.wap.id set
CALL cat.system.publish_changes(table => 'cat.db.t', id => 'wap-123'); // unknown
// after
spark.conf.set("spark.wap.id", "wap-123"); // on the writing job, before commit
CALL cat.system.publish_changes(table => 'cat.db.t', id => 'wap-123');
Defensive patterns

Strategy: validation

Validate before calling

val found = spark.table("cat.db.t.snapshots").where("properties[\"write.wap.id\"] = wapId").count()
if (found == 0) fail(s"no staged snapshot with wap.id $wapId")

Try / catch

try { spark.sql(call) } catch { case e: ValidationException if e.getMessage.contains("unknown WAP ID") => /* verify write job and id */ }

Prevention

When it happens

Trigger: Calling publish_changes with an id that was never written, was already published (WAP ID removed after cherry-pick), or belongs to a different table; also typos or case mismatches in the id string.

Common situations: Running publish_changes before the staged write job committed; calling it twice for the same WAP ID (first call consumes it); pointing the procedure at the wrong table; spark.wap.id not set on the writing job so no staged snapshot got an ID.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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