apache/iceberg · warning
Failed to load committed snapshot: omitting sequence number…
Error message
Failed to load committed snapshot: omitting sequence number from notifications
What it means
After committing a snapshot, MergingSnapshotProducer notifies listeners using the just-saved snapshot. If the snapshot cannot be found in the (refreshed) table metadata — typically because the latest metadata couldn't be loaded due to eventual-consistency problems during refresh — this WARN is logged, the sequence number is set to INVALID_SEQUENCE_NUMBER, and notifications are emitted without it.
Solutions
- Use a catalog/storage backend with strong read-after-write consistency so the committed snapshot is immediately visible on refresh.
- Retry the refresh or add a short delay before reading metadata in code that triggers notification right after commit.
- If you consume notifications downstream, tolerate a null/invalid sequence number rather than assuming it is always set.
- Upgrade the catalog implementation if known eventual-consistency behavior is causing frequent occurrences.
Example fix
// before (listener assumes sequence number always present)
long seq = notification.sequenceNumber();
// after
long seq = notification.sequenceNumber() != TableMetadata.INVALID_SEQUENCE_NUMBER
? notification.sequenceNumber()
: -1L; // handle missing sequence number Defensive patterns
Strategy: try-catch
Validate before calling
// after commit, confirm the snapshot is visible before notifying
if (table.operations().current().snapshot(snapshotId) == null) {
// metadata not yet visible (eventual consistency) — handle missing sequence number
} Type guard
static boolean hasSequenceNumber(Snapshot s) {
return s != null && s.sequenceNumber() != TableMetadata.INVALID_SEQUENCE_NUMBER;
} Try / catch
try {
long seq = justSaved.sequenceNumber();
} catch (NullPointerException | IllegalStateException e) {
long seq = TableMetadata.INVALID_SEQUENCE_NUMBER; // degrade notifications
} Prevention
- Use strongly consistent catalogs/stores so committed snapshots are visible immediately.
- Design downstream notification consumers to tolerate invalid/absent sequence numbers.
- Add retry/delay around refresh-after-commit in custom commit flows.
- Track how often this WARN fires as an eventual-consistency signal for your storage.
When it happens
Trigger: A commit succeeds on the catalog, then table.refresh()/loading the current metadata fails to observe the new snapshot immediately (eventually consistent catalog or object store); notify listeners path runs with justSaved == null.
Common situations: Eventually consistent object stores (e.g. S3 without strong read-after-write) backing a Hadoop/FileIO catalog; slow catalog propagation right after commit; listeners (e.g. Spark listener buses, event hooks) observing notifications missing sequence numbers.
Related errors
- Cannot find snapshot after
- Cannot find snapshot older than
- DuplicateWAPCommitException(wapId)
- Failed on snapshot while reading manifest list
- Failed to load committed snapshot, skipping manifest…
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/3f14e7c20b7bd026.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/apache/iceberg/MergingSnapshotProducer.java:1101
return manifests;
}
@Override
public Object updateEvent() {
long snapshotId = snapshotId();
Snapshot justSaved = ops().current().snapshot(snapshotId);
if (justSaved == null) {
justSaved = ops().refresh().snapshot(snapshotId);
}
long sequenceNumber = TableMetadata.INVALID_SEQUENCE_NUMBER;
Map<String, String> summary;
if (justSaved == null) {
// The snapshot just saved may not be present if the latest metadata couldn't be loaded due to
// eventual
// consistency problems in refresh.
LOG.warn("Failed to load committed snapshot: omitting sequence number from notifications");
summary = summary();
} else {
sequenceNumber = justSaved.sequenceNumber();
summary = justSaved.summary();
}
return new CreateSnapshotEvent(tableName, operation(), snapshotId, sequenceNumber, summary);
}
@Override
protected void cleanUncommitted(Set<ManifestFile> committed) {
mergeManager.cleanUncommitted(committed);
filterManager.cleanUncommitted(committed);
deleteMergeManager.cleanUncommitted(committed);
deleteFilterManager.cleanUncommitted(committed);
cleanUncommittedAppends(committed);
}
View on GitHub (pinned to 86d9c8fc54)