apache/iceberg · warning
Commit status check: Commit to {} of {} unknown, new metadat
Error message
Commit status check: Commit to {} of {} unknown, new metadata location is not current or in history What it means
This is a WARN log, not a thrown exception: after a commit whose outcome is unclear (e.g. an HTTP timeout), Iceberg re-checks the metastore to determine whether the commit actually succeeded. When the new metadata location is neither the table's current location nor in its history, the commit is definitively a failure, but since the original error was ambiguous, the method conservatively returns CommitStatus.UNKNOWN instead of FAILURE. Callers treat UNKNOWN as unrecoverable and propagate a CommitFailedException-style uncertainty to the user.
Source
Thrown at core/src/main/java/org/apache/iceberg/BaseMetastoreOperations.java:72
* CommitStatus#UNKNOWN}, because possible pending retries might still commit the change.
*
* @param tableOrViewName full name of the Table/View
* @param newMetadataLocation the path of the new commit file
* @param properties properties for retry
* @param commitStatusSupplier check if the latest metadata presents or not using metadata
* location for table.
* @return Commit Status of Success or Unknown
*/
protected CommitStatus checkCommitStatus(
String tableOrViewName,
String newMetadataLocation,
Map<String, String> properties,
Supplier<Boolean> commitStatusSupplier) {
CommitStatus strictStatus =
checkCommitStatusStrict(
tableOrViewName, newMetadataLocation, properties, commitStatusSupplier);
if (strictStatus == CommitStatus.FAILURE) {
LOG.warn(
"Commit status check: Commit to {} of {} unknown, new metadata location is not current "
+ "or in history",
tableOrViewName,
newMetadataLocation);
return CommitStatus.UNKNOWN;
}
return strictStatus;
}
/**
* Attempt to load the content and see if any current or past metadata location matches the one we
* were attempting to set. This is used as a last resort when we are dealing with exceptions that
* may indicate the commit has failed and don't have proof that this is the case, but we can be
* sure that no retry attempts for the commit will be successful later. Note that all the previous
* locations must also be searched on the chance that a second committer was able to successfully
* commit on top of our commit. When the {@code newMetadataLocation} is not in the history the
* method returns {@link CommitStatus#FAILURE}, when the {@code commitStatusSupplier} fails
* repeatedly the method returns {@link CommitStatus#UNKNOWN}.View on GitHub (pinned to 86d9c8fc54)
Solutions
- Re-run the commit operation; UNKNOWN status means the table was not modified by this commit so a fresh commit is safe.
- Check the table's current metadata location in the metastore to identify which concurrent writer won.
- Reduce commit concurrency or use a catalog with proper atomic commit semantics (e.g. REST catalog with conditional writes) instead of racing clients.
- Enable debug logging on the operations class to compare the expected vs actual metadata location.
Example fix
// before: retrying inside the same failed commit context
try { table.updateSchema()...commit(); } catch (CommitFailedException e) { /* uncertain */ }
// after: reload and re-apply on UNKNOWN status
Table reloaded = catalog.loadTable(identifier);
reloaded.updateSchema().addColumn("new_col", Types.LongType.get()).commit(); Defensive patterns
Strategy: retry
Validate before calling
// before committing, check current metadata location matches your last-read state TableMetadata current = ((HasTableOperations) table).operations().current(); boolean stillCurrent = current.metadataFileLocation().equals(lastSeenMetadataLocation);
Try / catch
try { table.refresh(); /* reapply changes */ table.updateSpec()...commit(); } catch (CommitFailedException e) { // reload table and reapply from scratch } Prevention
- Always reload the table and reapply changes after any uncertain commit outcome
- Minimize concurrent writers to the same table
- Use catalogs with strong atomic commit guarantees
- Log metadata locations to trace which writer won a race
When it happens
Trigger: checkCommitStatus is invoked after a commit exception; checkCommitStatusStrict determined FAILURE because the metadata location in the metastore is different and newMetadataLocation is absent from the version history stored in the 'previous-versions'/'metadata-log' properties.
Common situations: Concurrent writers where another client committed a different snapshot before this commit; Hive/Glue/Nessie metastores where commit racing is common; network timeouts during commit causing retry logic to run the status check.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- The view %s.%s has been modified concurrently
- Could not acquire the lock on %s.%s, lock request ended in s
- Cannot commit %s: concurrent update detected
- Cannot commit %s because base metadata location '%s' is not
- Cannot find Glue table %s after refresh, maybe another proce
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/7bd3e373da600849.
Report an issue: GitHub.