spring-projects/spring-ai · error · RuntimeException
Unsupported clone for MessageDigest.
Error message
Unsupported clone for MessageDigest.
What it means
getMessageDigest() clones the generator's prototype MessageDigest so each hash computation gets fresh state; if the digest implementation does not support clone() it throws CloneNotSupportedException, wrapped in RuntimeException('Unsupported clone for MessageDigest.'). Standard SunJCE digests support cloning, so this indicates a custom or provider-specific MessageDigest.
Solutions
- Switch to a JDK-built-in algorithm (SHA-256) via the no-arg constructor
- Avoid HSM/provider-backed digests for id generation; use a software provider
- Create a new JdkSha256HexIdGenerator per hash instead of reusing the clone path
- Catch RuntimeException around generate() and fall back to a fresh instance
Example fix
// before IdGenerator gen = new JdkSha256HexIdGenerator(hsmDigestAlgorithm, UTF_8); // after IdGenerator gen = new JdkSha256HexIdGenerator(); // SHA-256 from SunJCE, cloneable
Defensive patterns
Strategy: try-catch
Try / catch
try {
id = gen.generate(content);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().contains("Unsupported clone")) {
id = new JdkSha256HexIdGenerator().generate(content); // software provider fallback
} else throw e;
} Prevention
- Use JDK built-in digest algorithms for id generation
- Avoid HSM/provider-backed MessageDigest in id generators
- Pin a software JCE provider (SunJCE) for hashing paths
When it happens
Trigger: Using a JdkSha256HexIdGenerator constructed with a custom algorithm whose MessageDigest provider implementation does not override/allow clone(), then calling generate()/hashBytes().
Common situations: Third-party crypto providers (BouncyCastle in certain modes, hardware/HSM-backed providers) that return non-clonable digest instances.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/6c214efa92bb8cb0.
Report an issue: GitHub.
Appendix: source
Thrown at spring-ai-commons/src/main/java/org/springframework/ai/document/id/JdkSha256HexIdGenerator.java:93
Assert.notNull(contents, "Contents must not be null");
try (ByteArrayOutputStream byteOut = new ByteArrayOutputStream()) {
ObjectOutputStream out = new ObjectOutputStream(byteOut);
for (Object content : contents) {
out.writeObject(content);
}
return byteOut.toByteArray();
}
catch (Exception e) {
throw new RuntimeException("Failed to serialize", e);
}
}
MessageDigest getMessageDigest() {
try {
return (MessageDigest) this.messageDigest.clone();
}
catch (CloneNotSupportedException e) {
throw new RuntimeException("Unsupported clone for MessageDigest.", e);
}
}
}
View on GitHub (pinned to 98a7beda4f)