apache/iceberg · error · RuntimeException

Unable to produce hash of table metadata

Error message

Unable to produce hash of table metadata

What it means

HMSTablePropertyHelper.hashOf() throws RuntimeException when it fails to serialize TableMetadata to JSON or compute its SHA-256 hash, e.g. NoSuchAlgorithmException (SHA-256 unavailable) or IOException from the JSON generator/hash writer plumbing.

Solutions

  1. Use a standard JDK/JCE provider that includes SHA-256
  2. Inspect the chained cause for the actual serialization/IO problem
  3. Report/fix if TableMetadataParser.toJson fails on specific metadata content

Example fix

// before
new HashWriter("SHA-256", ...); // NoSuchAlgorithmException
// after
// run on full JDK (e.g. Temurin) where SHA-256 is always available
Defensive patterns

Strategy: try-catch

Try / catch

try { /* property update path */ } catch (RuntimeException e) { if (e.getCause() instanceof NoSuchAlgorithmException || e.getCause() instanceof IOException) { /* handle serialization failure */ } }

Prevention

When it happens

Trigger: Computing the metadata hash during table property updates when the JVM lacks the SHA-256 algorithm or the JsonGenerator/HashWriter pipeline throws IOException.

Common situations: Running on a restricted JRE without SHA-256 (rare); I/O errors in the in-memory hash stream; bugs in metadata parser serialization.

Understand the failure class

Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/f3fb719edaaceae4. Report an issue: GitHub.

Appendix: source

Thrown at hive-metastore/src/main/java/org/apache/iceberg/hive/HMSTablePropertyHelper.java:305

    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);
    }
  }

  private static void setField(
      Map<String, String> parameters, String key, String value, long maxHiveTablePropertySize) {
    if (value.length() <= maxHiveTablePropertySize) {
      parameters.put(key, value);
    } else {
      LOG.warn(
          "Not exposing {} in HMS since it exceeds {} characters", key, maxHiveTablePropertySize);
    }
  }

  private static boolean exposeInHmsProperties(long maxHiveTablePropertySize) {
    return maxHiveTablePropertySize > 0;
  }
}

View on GitHub (pinned to 86d9c8fc54)