{"record":{"id":"d2c07809a725ba7a","repo":"spring-projects/spring-ai","slug":"sha-256-not-available","errorCode":null,"errorMessage":"SHA-256 not available","messagePattern":"SHA-256 not available","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"advisors/spring-ai-tool-search-advisor/src/main/java/org/springframework/ai/chat/client/advisor/toolsearch/ToolSearchToolCallingAdvisor.java","lineNumber":350,"sourceCode":"\t/**\n\t * Computes a stable SHA-256 fingerprint for the given tool set. Tools are sorted by\n\t * name so that registration order does not affect equality. Hashing avoids false\n\t * cache hits that string-concatenation with delimiters can produce when names or\n\t * summaries contain those delimiter characters.\n\t */\n\tprivate static String computeFingerprint(List<ToolReference> toolReferences) {\n\t\ttry {\n\t\t\tMessageDigest digest = MessageDigest.getInstance(\"SHA-256\");\n\t\t\ttoolReferences.stream().sorted(Comparator.comparing(ToolReference::toolName)).forEachOrdered(tr -> {\n\t\t\t\tdigest.update(tr.toolName().getBytes(StandardCharsets.UTF_8));\n\t\t\t\tdigest.update((byte) 0); // field separator\n\t\t\t\tdigest.update(tr.summary().getBytes(StandardCharsets.UTF_8));\n\t\t\t\tdigest.update((byte) 1); // entry separator\n\t\t\t});\n\t\t\treturn HexFormat.of().formatHex(digest.digest());\n\t\t}\n\t\tcatch (NoSuchAlgorithmException e) {\n\t\t\tthrow new IllegalStateException(\"SHA-256 not available\", e);\n\t\t}\n\t}\n\n\t// -------------------------------------------------------------------------\n\t// Builder\n\t// -------------------------------------------------------------------------\n\n\t/**\n\t * Creates a new Builder instance for constructing a ToolSearchToolCallingAdvisor.\n\t * @return a new Builder instance\n\t */\n\tpublic static Builder<?> builder() {\n\t\treturn new Builder<>();\n\t}\n\n\t/**\n\t * Builder for creating instances of ToolSearchToolCallingAdvisor.\n\t * <p>","sourceCodeStart":332,"sourceCodeEnd":368,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/advisors/spring-ai-tool-search-advisor/src/main/java/org/springframework/ai/chat/client/advisor/toolsearch/ToolSearchToolCallingAdvisor.java#L332-L368","documentation":"This IllegalStateException is thrown when the JVM cannot provide a SHA-256 MessageDigest while ToolSearchToolCallingAdvisor.computeFingerprint builds a hash of the tool list (tool names, descriptions and summaries are fed into the digest and hex-encoded). SHA-256 is mandated by the Java specification to exist in every JDK, so this failure indicates a broken or non-compliant JCA provider configuration rather than normal usage.","triggerScenarios":"Calling fingerprint()/build() of ToolSearchToolCallingAdvisor when MessageDigest.getInstance(\"SHA-256\") throws NoSuchAlgorithmException — i.e. no JCA provider offers SHA-256.","commonSituations":"Running on a stripped-down JVM or custom runtime (e.g. a heavily trimmed jlink image without the SUN provider), a broken java.security configuration file that removed the SUN provider, or exotic JDK distributions without standard providers.","solutions":["Use a standard, unmodified JDK/JRE (Temurin, Oracle, Corretto) that includes the SUN security provider with SHA-256.","Check java.security config (JAVA_HOME/conf/security/java.security) and restore the SUN provider entry if it was removed.","If using jlink, include the org.builtin.providers / jdk.crypto modules in the custom runtime image.","If you cannot fix the runtime, upgrade spring-ai or wrap advisor creation to fail fast with a clearer message."],"exampleFix":"// before (broken custom runtime)\njava -module-path custom-modules ... // no jdk.crypto.evr/sun provider\n\n// after\njlink --add-modules java.base,jdk.crypto.ec,java.security.jgss --output myruntime","handlingStrategy":"try-catch","validationCode":"try { MessageDigest.getInstance(\"SHA-256\"); } catch (NoSuchAlgorithmException e) { throw new IllegalStateException(\"Runtime lacks SHA-256; check JCA providers\", e); }","typeGuard":"boolean sha256Available() { try { MessageDigest.getInstance(\"SHA-256\"); return true; } catch (NoSuchAlgorithmException e) { return false; } }","tryCatchPattern":"try {\n    advisor = ToolSearchToolCallingAdvisor.builder().build();\n} catch (IllegalStateException e) {\n    if (e.getCause() instanceof NoSuchAlgorithmException) {\n        throw new RuntimeException(\"JVM JCA providers missing SHA-256; use a standard JDK\", e);\n    }\n    throw e;\n}","preventionTips":["Use a standard JDK distribution (Temurin/Corretto/Oracle)","Never remove the SUN provider from java.security","Include jdk.crypto modules in jlink custom runtimes","Add a startup smoke test hashing a known value"],"tags":["jvm","security","hashing","configuration"],"backgroundTag":"internal-invariant-violation","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}