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
- Confirm the staged write ran with spark.wap.id set to the same value, and that the job committed
- Inspect table.snapshots (or the snapshots metadata table) to find existing wap IDs: SELECT * FROM cat.db.t.snapshots
- Use the correct table identifier in the procedure call
- 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
- Set spark.wap.id on the writing job before commit
- Check the snapshots metadata table for existing WAP IDs before calling
- Remember publish_changes consumes the staged snapshot — don't call twice with the same id
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
- Cannot apply non-unique WAP ID. Found multiple snapshots wit
- Cannot apply unknown WAP ID '${wapId}'
- Cannot apply unknown WAP ID '%s'
- Cannot apply non-unique WAP ID. Found multiple snapshots wit
- Couldn't load table '${ident}' in catalog '${tableCatalog.na
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/c1129b91664393af.
Report an issue: GitHub.