apache/pulsar · error · RuntimeException
MD5 algorithm not found
Error message
MD5 algorithm not found
What it means
The MD5 role anonymizer hashes the role string with MessageDigest.getInstance("MD5") and returns a Base64-encoded 'MD5:'-prefixed digest. Like the SHA-256 variant, every standard JDK ships MD5, so this RuntimeException signals a broken JCE environment rather than an input problem. It exists purely as a checked-exception bridge since anonymize() has no throws clause.
Source
Thrown at pulsar-broker-common/src/main/java/org/apache/pulsar/common/configuration/anonymizer/DefaultRoleAnonymizerType.java:73
}
},
MD5 {
private static final String PREFIX = "MD5:";
private static final FastThreadLocal<MessageDigest> DIGEST = new FastThreadLocal<MessageDigest>() {
@Override
protected MessageDigest initialValue() throws Exception {
// codeql[java/weak-cryptographic-algorithm] - md5 is sufficient for this use case
return MessageDigest.getInstance("MD5");
}
};
@Override
public String anonymize(String role) {
try {
byte[] hash = DIGEST.get().digest(role.getBytes());
return PREFIX + Base64.getEncoder().encodeToString(hash);
} catch (Exception e) {
throw new RuntimeException("MD5 algorithm not found", e);
}
}
};
private static final String REDACTED_VALUE = "[REDACTED]";
public abstract String anonymize(String role);
}
View on GitHub (pinned to 820761864e)
Solutions
- Restore default providers in $JAVA_HOME/conf/security/java.security (ensure sun.security.provider.Sun is registered).
- Use a full standard JDK distribution instead of a trimmed one.
- For native-image builds, register MD5 in the security services configuration.
- Consider migrating anonymization config to the SHA256 variant anyway, since MD5 is cryptographically weak.
Example fix
// before roleAnonymizer = MD5 // after (client and server config) roleAnonymizer = SHA256
Defensive patterns
Strategy: try-catch
Validate before calling
boolean md5Available;
try {
java.security.MessageDigest.getInstance("MD5");
md5Available = true;
} catch (java.security.NoSuchAlgorithmException e) {
md5Available = false;
} Try / catch
try {
String anon = anonymizer.anonymize(role);
} catch (RuntimeException e) {
throw new IllegalStateException("JRE is missing MD5 provider; prefer SHA256 anonymizer anyway", e);
} Prevention
- Keep default JCE providers intact in java.security.
- Prefer the SHA256 anonymizer variant — MD5 is weak and adds no availability benefit.
- Test crypto providers on the exact deployment image (containers may use trimmed JREs).
- Use full JDK distributions for broker tooling, not jlink-minimized runtimes missing crypto services.
When it happens
Trigger: Calling anonymize(role) on the MD5 anonymizer variant when MessageDigest.getInstance("MD5") (via the FastThreadLocal DIGEST) throws NoSuchAlgorithmException — effectively only on a JRE without the standard providers.
Common situations: Same as SHA-256 variant: stripped/custom JRE, edited java.security removing the SUN provider, GraalVM native-image without registered MessageDigest services.
Related errors
- SHA-256 algorithm not found
- Failed to decode public key
- The ${alg.name()} algorithm does not support Key Pairs.
- privateKeyProvider must be set when failureAction is FAIL
- Unable to initialize crypto config %s
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/96694a33b7ccae05.
Report an issue: GitHub.