spring-projects/spring-ai · error · IllegalArgumentException
NoSuchAlgorithmException (wrapped IllegalArgumentException)
Error message
NoSuchAlgorithmException (wrapped IllegalArgumentException)
What it means
JdkSha256HexIdGenerator resolves a MessageDigest via MessageDigest.getInstance(algorithm) in its constructor; unsupported algorithm names throw NoSuchAlgorithmException, wrapped in IllegalArgumentException. The default constructor uses SHA-256, so this only occurs when supplying a custom algorithm.
Source
Thrown at spring-ai-commons/src/main/java/org/springframework/ai/document/id/JdkSha256HexIdGenerator.java:51
* @author Christian Tzolov
*/
public class JdkSha256HexIdGenerator implements IdGenerator {
private static final String SHA_256 = "SHA-256";
private final String byteHexFormat = "%02x";
private final Charset charset;
private final MessageDigest messageDigest;
public JdkSha256HexIdGenerator(final String algorithm, final Charset charset) {
this.charset = charset;
try {
this.messageDigest = MessageDigest.getInstance(algorithm);
}
catch (NoSuchAlgorithmException e) {
throw new IllegalArgumentException(e);
}
}
public JdkSha256HexIdGenerator() {
this(SHA_256, StandardCharsets.UTF_8);
}
@Override
public String generateId(Object... contents) {
return this.hash(this.serializeToBytes(contents));
}
// https://github.com/spring-projects/spring-ai/issues/113#issue-2000373318
private String hash(byte[] contentWithMetadata) {
byte[] hashBytes = getMessageDigest().digest(contentWithMetadata);
StringBuilder sb = new StringBuilder();
for (byte b : hashBytes) {
sb.append(String.format(this.byteHexFormat, b));View on GitHub (pinned to 98a7beda4f)
Solutions
- Use the no-arg constructor which defaults to SHA-256
- Use a standard JDK algorithm name: 'SHA-256', 'SHA-512', 'MD5'
- Check available algorithms: Security.getAlgorithms("MessageDigest")
- Catch IllegalArgumentException at construction and fall back to SHA-256
Example fix
// before
IdGenerator gen = new JdkSha256HexIdGenerator(config.getHashAlgo(), UTF_8);
// after
String algo = Security.getAlgorithms("MessageDigest").contains(config.getHashAlgo()) ? config.getHashAlgo() : "SHA-256";
IdGenerator gen = new JdkSha256HexIdGenerator(algo, UTF_8); Defensive patterns
Strategy: validation
Validate before calling
if (!Security.getAlgorithms("MessageDigest").contains(algorithm)) {
throw new IllegalArgumentException("Unsupported digest algorithm: " + algorithm);
}
new JdkSha256HexIdGenerator(algorithm, charset); Try / catch
try {
gen = new JdkSha256HexIdGenerator(algo, charset);
} catch (IllegalArgumentException e) {
gen = new JdkSha256HexIdGenerator(); // fallback to SHA-256
} Prevention
- Default to the no-arg SHA-256 constructor
- Validate algorithm names against Security.getAlgorithms("MessageDigest")
- Be aware of FIPS-hardened JVMs with restricted providers
When it happens
Trigger: new JdkSha256HexIdGenerator("SHA3-999", charset) or any algorithm string not provided by the installed JCE providers (typo like 'sha256' is usually fine — JDK is case-insensitive — but e.g. 'MD6' or a FIPS-restricted JDK lacking the algorithm fails).
Common situations: Configuring a custom hash algorithm via properties on a hardened/FIPS JVM where the requested provider isn't installed, or typos in algorithm names.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- SHA-256 not available
- Failed to read stdio connection resource
- SSE connection '<connectionName>' requires a 'url' property.
- Failed to create SSE transport for connection '<connectionNa
- The region '<region>' is not a valid region!
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/26959db37a74d63e.
Report an issue: GitHub.