{"record":{"id":"f7fd3d610297cf07","repo":"apache/iceberg","slug":"the-current-metadata-file-s-might-have-been-modif","errorCode":null,"errorMessage":"The current metadata file %s might have been modified. Hash of metadata loaded from storage differs from HMS-stored metadata hash.","messagePattern":"The current metadata file (.+?) might have been modified\\. Hash of metadata loaded from storage differs from HMS-stored metadata hash\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"hive-metastore/src/main/java/org/apache/iceberg/hive/HMSTablePropertyHelper.java","lineNumber":290,"sourceCode":"  }\n\n  @VisibleForTesting\n  static void setMetadataHash(TableMetadata metadata, Map<String, String> parameters) {\n    if (parameters.containsKey(TableProperties.ENCRYPTION_TABLE_KEY)) {\n      byte[] currentHashBytes = hashOf(metadata);\n      parameters.put(\n          BaseMetastoreTableOperations.METADATA_HASH_PROP,\n          Base64.getEncoder().encodeToString(currentHashBytes));\n    }\n  }\n\n  @VisibleForTesting\n  static void verifyMetadataHash(TableMetadata metadata, String metadataHashFromHMS) {\n    byte[] currentHashBytes = hashOf(metadata);\n    byte[] expectedHashBytes = Base64.getDecoder().decode(metadataHashFromHMS);\n\n    if (!Arrays.equals(expectedHashBytes, currentHashBytes)) {\n      throw new RuntimeException(\n          String.format(\n              \"The current metadata file %s might have been modified. Hash of metadata loaded from storage differs \"\n                  + \"from HMS-stored metadata hash.\",\n              metadata.metadataFileLocation()));\n    }\n  }\n\n  private static byte[] hashOf(TableMetadata tableMetadata) {\n    try (HashWriter hashWriter = new HashWriter(\"SHA-256\", StandardCharsets.UTF_8);\n        JsonGenerator generator = JsonUtil.factory().createGenerator(hashWriter)) {\n      TableMetadataParser.toJson(tableMetadata, generator);\n      generator.flush();\n      return hashWriter.getHash();\n    } catch (NoSuchAlgorithmException | IOException e) {\n      throw new RuntimeException(\"Unable to produce hash of table metadata\", e);\n    }\n  }\n","sourceCodeStart":272,"sourceCodeEnd":308,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/hive-metastore/src/main/java/org/apache/iceberg/hive/HMSTablePropertyHelper.java#L272-L308","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\n// metadata file overwritten externally, HMS hash stale\n// after\n// re-commit the table via HiveCatalog so HMS parameters are updated with the new hash","handlingStrategy":"try-catch","validationCode":"// before committing, re-read the table through HiveCatalog and confirm no external writers; compare current HMS hash with your base metadata","typeGuard":null,"tryCatchPattern":"try { catalog.loadTable(ident); } catch (RuntimeException e) { if (e.getMessage().contains(\"might have been modified\")) { /* reload metadata / resolve external writer */ } }","preventionTips":["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"],"tags":["hive","metadata","integrity","checksum"],"backgroundTag":"checksum-mismatch","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}