apache/iceberg · error · RuntimeException
The current metadata file
Error message
The current metadata file %s might have been modified. Hash of metadata loaded from storage differs from HMS-stored metadata hash.
What it means
HMSTablePropertyHelper.verifyMetadataHash() throws RuntimeException when the SHA-256 hash of the table metadata loaded from storage does not match the hash stored in the Hive metastore table parameters. This guards against out-of-band modification of the Iceberg metadata file that HMS still believes it owns.
Solutions
- Identify and stop out-of-band writers; commit only through the HiveCatalog
- Force a refresh/commit through HMS so the stored hash is recomputed
- Remove the stale metadata hash parameter to reset the check if intentional
- Restore consistent metadata file matching the HMS-stored hash
Example fix
// before // metadata file overwritten externally, HMS hash stale // after // re-commit the table via HiveCatalog so HMS parameters are updated with the new hash
Defensive patterns
Strategy: try-catch
Validate before calling
// before committing, re-read the table through HiveCatalog and confirm no external writers; compare current HMS hash with your base metadata
Try / catch
try { catalog.loadTable(ident); } catch (RuntimeException e) { if (e.getMessage().contains("might have been modified")) { /* reload metadata / resolve external writer */ } } Prevention
- Never write metadata files outside the HiveCatalog commit path
- One catalog implementation per table across jobs
- Avoid restoring old metadata files from backups into live locations
When it happens
Trigger: The metadata file at metadata.metadataFileLocation() was modified or replaced after HMS recorded its hash; a different writer updated the table outside HMS coordination; hash property in HMS parameters is stale or corrupted.
Common situations: Direct writes to the table location bypassing the Hive catalog; concurrent commits from a different catalog implementation; manually edited/corrupted metastore parameters; restoring old metadata files from backup.
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
- Full metadata integrity check skipped because no metadata…
- Unable to produce hash of table metadata
- Cannot call acquireLock twice for
- Cannot create namespace " + namespace + ": metadata is not…
- Could not acquire the lock on
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/f7fd3d610297cf07.
Report an issue: GitHub.
Appendix: source
Thrown at hive-metastore/src/main/java/org/apache/iceberg/hive/HMSTablePropertyHelper.java:290
}
@VisibleForTesting
static void setMetadataHash(TableMetadata metadata, Map<String, String> parameters) {
if (parameters.containsKey(TableProperties.ENCRYPTION_TABLE_KEY)) {
byte[] currentHashBytes = hashOf(metadata);
parameters.put(
BaseMetastoreTableOperations.METADATA_HASH_PROP,
Base64.getEncoder().encodeToString(currentHashBytes));
}
}
@VisibleForTesting
static void verifyMetadataHash(TableMetadata metadata, String metadataHashFromHMS) {
byte[] currentHashBytes = hashOf(metadata);
byte[] expectedHashBytes = Base64.getDecoder().decode(metadataHashFromHMS);
if (!Arrays.equals(expectedHashBytes, currentHashBytes)) {
throw new RuntimeException(
String.format(
"The current metadata file %s might have been modified. Hash of metadata loaded from storage differs "
+ "from HMS-stored metadata hash.",
metadata.metadataFileLocation()));
}
}
private static byte[] hashOf(TableMetadata tableMetadata) {
try (HashWriter hashWriter = new HashWriter("SHA-256", StandardCharsets.UTF_8);
JsonGenerator generator = JsonUtil.factory().createGenerator(hashWriter)) {
TableMetadataParser.toJson(tableMetadata, generator);
generator.flush();
return hashWriter.getHash();
} catch (NoSuchAlgorithmException | IOException e) {
throw new RuntimeException("Unable to produce hash of table metadata", e);
}
}
View on GitHub (pinned to 86d9c8fc54)