{"record":{"id":"fdf1f6cea4984906","repo":"apache/pulsar","slug":"sha-256-algorithm-not-found","errorCode":null,"errorMessage":"SHA-256 algorithm not found","messagePattern":"SHA-256 algorithm not found","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"pulsar-broker-common/src/main/java/org/apache/pulsar/common/configuration/anonymizer/DefaultRoleAnonymizerType.java","lineNumber":53,"sourceCode":"         return REDACTED_VALUE;\n      }\n   },\n   SHA256 {\n      private static final String PREFIX = \"SHA-256:\";\n      private static final FastThreadLocal<MessageDigest> DIGEST = new FastThreadLocal<MessageDigest>() {\n         @Override\n         protected MessageDigest initialValue() throws Exception {\n            return MessageDigest.getInstance(\"SHA-256\");\n         }\n      };\n\n      @Override\n      public String anonymize(String role) {\n         try {\n            byte[] hash = DIGEST.get().digest(role.getBytes());\n            return PREFIX + Base64.getEncoder().encodeToString(hash);\n         } catch (Exception e) {\n            throw new RuntimeException(\"SHA-256 algorithm not found\", e);\n         }\n      }\n   },\n   MD5 {\n      private static final String PREFIX = \"MD5:\";\n      private static final FastThreadLocal<MessageDigest> DIGEST = new FastThreadLocal<MessageDigest>() {\n         @Override\n         protected MessageDigest initialValue() throws Exception {\n            // codeql[java/weak-cryptographic-algorithm] - md5 is sufficient for this use case\n            return MessageDigest.getInstance(\"MD5\");\n         }\n      };\n\n      @Override\n      public String anonymize(String role) {\n         try {\n            byte[] hash = DIGEST.get().digest(role.getBytes());\n            return PREFIX + Base64.getEncoder().encodeToString(hash);","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker-common/src/main/java/org/apache/pulsar/common/configuration/anonymizer/DefaultRoleAnonymizerType.java#L35-L71","documentation":"The SHA-256 role anonymizer hashes the role string with MessageDigest.getInstance(\"SHA-256\") and returns a Base64-encoded 'SHA256:'-prefixed digest. The JDK guarantees SHA-256 in every standard JRE, so this RuntimeException only fires when no SHA-256 provider can be found — i.e. the JCE provider list is broken or a heavily trimmed/custom JDK is in use. It is a defensive wrapper; in practice it indicates a broken runtime environment rather than bad input.","triggerScenarios":"Calling anonymize(role) on the SHA256 anonymizer variant when MessageDigest.getInstance(\"SHA-256\") (cached via the FastThreadLocal DIGEST) throws NoSuchAlgorithmException — effectively only on a JRE lacking the SUN provider.","commonSituations":"Running Pulsar on a stripped-down/custom JRE without standard crypto providers; a broken java.security configuration (mis-edited java.security file removing the SUN provider); exotic runtimes (some GraalVM native-image configs not registering the provider).","solutions":["Restore the default JCE providers: check $JAVA_HOME/conf/security/java.security still lists security.provider.1=sun.security.provider.Sun (or equivalent).","Run on a standard, unmodified JDK (Temurin/OpenJDK 8/11/17+) instead of a stripped runtime.","If using GraalVM native-image, register SHA-256 with the native-image security services configuration (native-image.properties / resource config).","Inspect the cause of the wrapping exception to confirm NoSuchAlgorithmException and which provider lookup failed."],"exampleFix":"// before (java.security mis-edited)\n#security.provider.1=sun.security.provider.Sun\n// after\nsecurity.provider.1=sun.security.provider.Sun\nsecurity.provider.2=sun.security.rsa.SunRsaSign\n...","handlingStrategy":"try-catch","validationCode":"// Verify SHA-256 availability before enabling the anonymizer\nboolean sha256Available;\ntry {\n    java.security.MessageDigest.getInstance(\"SHA-256\");\n    sha256Available = true;\n} catch (java.security.NoSuchAlgorithmException e) {\n    sha256Available = false;\n}","typeGuard":null,"tryCatchPattern":"try {\n    String anon = anonymizer.anonymize(role);\n} catch (RuntimeException e) {\n    throw new IllegalStateException(\"JRE is missing SHA-256 provider; check java.security and JDK\", e);\n}","preventionTips":["Run on an unmodified standard JDK (Temurin/OpenJDK).","Never remove default security.provider entries from java.security.","For GraalVM native-image, register MessageDigest.SHA-256 in the services configuration.","Smoke-test MessageDigest.getInstance(\"SHA-256\") in CI on the actual runtime image."],"tags":["java","security","crypto","configuration"],"backgroundTag":"missing-crypto-algorithm","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}