skylot/jadx · critical · JadxRuntimeException
Failed to build hash
Error message
Failed to build hash
What it means
Thrown by md5Sum(byte[]) when MessageDigest.getInstance("MD5") fails. MD5 is a mandatory algorithm in every standard Java JDK (mandated by JCA specification), so NoSuchAlgorithmException should never occur in a compliant JVM. The only realistic trigger is a non-compliant or severely stripped/custom JVM (e.g., a minimal embedded JVM, or a security provider configuration that removed MD5). The catch is defensive.
Source
Thrown at jadx-core/src/main/java/jadx/core/utils/files/FileUtils.java:501
public static List<Path> fileNamesToPaths(List<String> fileNames) {
return fileNames.stream().map(Paths::get).collect(Collectors.toList());
}
public static List<File> toFiles(List<Path> paths) {
return paths.stream().map(Path::toFile).collect(Collectors.toList());
}
public static String md5Sum(String str) {
return md5Sum(str.getBytes(StandardCharsets.UTF_8));
}
public static String md5Sum(byte[] data) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(data);
return bytesToHex(md.digest());
} catch (Exception e) {
throw new JadxRuntimeException("Failed to build hash", e);
}
}
/**
* Hash timestamps of input files
*/
public static String buildInputsHash(List<Path> inputPaths) {
try (ByteArrayOutputStream bout = new ByteArrayOutputStream();
DataOutputStream data = new DataOutputStream(bout)) {
List<Path> inputFiles = FileUtils.expandDirs(inputPaths);
Collections.sort(inputFiles);
data.write(inputPaths.size());
data.write(inputFiles.size());
for (Path inputFile : inputFiles) {
FileTime modifiedTime = Files.getLastModifiedTime(inputFile);
data.writeLong(modifiedTime.toMillis());
}
return FileUtils.md5Sum(bout.toByteArray());View on GitHub (pinned to e738a26571)
Solutions
- Use a standard JDK (Oracle, OpenJDK, or a JCA-compliant JVM) that includes MD5.
- Check installed security providers: java.security.Security.getProviders() and verify MessageDigest hash algorithms.
- If MD5 was intentionally removed, patch md5Sum to use an alternative like SHA-256.
Example fix
// before
MessageDigest md = MessageDigest.getInstance("MD5"); // can throw
// after — verify provider support at startup
if (MessageDigest.isAvailable("MD5")) { // Java 17+; otherwise try/catch
md = MessageDigest.getInstance("MD5");
} else {
md = MessageDigest.getInstance("SHA-256");
} Defensive patterns
Strategy: try-catch
Validate before calling
// Check MD5 availability before use
public static boolean isMd5Available() {
try {
MessageDigest.getInstance("MD5");
return true;
} catch (Exception e) {
return false;
}
} Try / catch
try {
String hash = FileUtils.md5Sum(data);
} catch (JadxRuntimeException e) {
if (e.getCause() instanceof NoSuchAlgorithmException) {
// MD5 not available — use alternative or report environment issue
LOG.error("MD5 not available on this JVM: {}", e.getCause().getMessage());
}
} Prevention
- Use a standard JCA-compliant JDK that includes MD5.
- Verify security providers at startup if running in a non-standard environment.
- If MD5 is intentionally unavailable, patch md5Sum to use SHA-256.
When it happens
Trigger: Running jadx on a non-standard JVM that does not include the MD5 algorithm. A custom security.provider configuration that explicitly deregisters MD5. An extremely minimal/embedded JVM that omits MessageDigest support.
Common situations: Embedded device JVMs with reduced crypto. A security policy (Java Security Manager or custom provider) that removed MD5. Extremely rare in practice — standard Oracle/OpenJDK, GraalVM, and Android all include MD5.
Related errors
- Failed to build hash for inputs
- Config file extension should be '.json'
- Failed to save JSON file: {}
- Failed to save JSON file: {}
- Failed to init common directories
AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14).
Data as JSON: /api/errors/f2c74c8edb63d77b.
Report an issue: GitHub.