{"record":{"id":"69cda99f1ad7a8cb","repo":"Tencent/matrix","slug":"initialize-md5-failed","errorCode":null,"errorMessage":"Initialize MD5 failed.","messagePattern":"Initialize MD5 failed\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"matrix/matrix-android/matrix-android-lib/src/main/java/com/tencent/matrix/util/MatrixUtil.java","lineNumber":224,"sourceCode":"     */\n    public static void closeQuietly(Closeable closeable) {\n        try {\n            if (closeable != null) {\n                closeable.close();\n            }\n        } catch (IOException e) {\n            Log.w(TAG, \"Failed to close resource\", e);\n        }\n    }\n\n    private static char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};\n    private final static ThreadLocal<MessageDigest> MD5_DIGEST = new ThreadLocal<MessageDigest>() {\n        @Override\n        protected MessageDigest initialValue() {\n            try {\n                return MessageDigest.getInstance(\"MD5\");\n            } catch (NoSuchAlgorithmException e) {\n                throw new RuntimeException(\"Initialize MD5 failed.\", e);\n            }\n        }\n    };\n\n    public static String getMD5String(String s) {\n        return getMD5String(s.getBytes());\n    }\n\n    public static String getMD5String(byte[] bytes) {\n        MessageDigest digest = MD5_DIGEST.get();\n        return bufferToHex(digest.digest(bytes));\n    }\n\n    private final static ThreadLocal<MessageDigest> SHA256_DIGEST = new ThreadLocal<MessageDigest>() {\n        @Override\n        protected MessageDigest initialValue() {\n            try {\n                return MessageDigest.getInstance(\"SHA-256\");","sourceCodeStart":206,"sourceCodeEnd":242,"githubUrl":"https://github.com/Tencent/matrix/blob/3b8293bd65d47eeea7caf1f32a3a5d4d5eab60e7/matrix/matrix-android/matrix-android-lib/src/main/java/com/tencent/matrix/util/MatrixUtil.java#L206-L242","documentation":"MatrixUtil's MD5 ThreadLocal wraps MessageDigest.getInstance(\"MD5\") and throws a RuntimeException when the JCA provider reports NoSuchAlgorithmException. MD5 is mandated by every standard Java/Android platform, so this only fires on broken or non-compliant crypto provider environments.","triggerScenarios":"MessageDigest.getInstance(\"MD5\") throwing NoSuchAlgorithmException inside the ThreadLocal's initialValue() when getMD5String first runs on a thread.","commonSituations":"Heavily stripped JRE/Android builds with removed crypto providers; custom Provider configurations that unregister default algorithms; exotic JVMs or security policy setups (e.g. some embedded or hardened environments).","solutions":["Restore/verify the default security Providers (e.g. Security.addProvider(new BouncyCastleProvider()))","Check java.security config files and registered providers for missing MD5 support","Catch the RuntimeException and use an alternative hashing path or fail gracefully","Log Security.getProviders() output at startup to diagnose provider stripping"],"exampleFix":"// before\nString md5 = MatrixUtil.getMD5String(data); // may throw\n\n// after\ntry {\n    String md5 = MatrixUtil.getMD5String(data);\n} catch (RuntimeException e) {\n    if (e.getCause() instanceof NoSuchAlgorithmException) {\n        Security.addProvider(new BouncyCastleProvider());\n    }\n    throw e;\n}","handlingStrategy":"try-catch","validationCode":"try {\n    MessageDigest.getInstance(\"MD5\");\n} catch (NoSuchAlgorithmException e) {\n    Security.addProvider(new BouncyCastleProvider());\n}","typeGuard":null,"tryCatchPattern":"try {\n    String md5 = MatrixUtil.getMD5String(data);\n} catch (RuntimeException e) {\n    if (e.getCause() instanceof NoSuchAlgorithmException) {\n        Security.addProvider(new BouncyCastleProvider());\n        // retry once or fall back to another hash\n    } else { throw e; }\n}","preventionTips":["Verify at app startup that MessageDigest.getInstance(\"MD5\") succeeds","Do not strip default security providers from the build","Log Security.getProviders() in diagnostics to catch provider issues early"],"tags":["android","crypto","md5","threadlocal"],"backgroundTag":"module-init-failed","analyzedSha":"3b8293bd65d47eeea7caf1f32a3a5d4d5eab60e7","analyzedAt":"2026-09-08T08:01:39.722Z","contentChangedAt":"2026-09-08T08:01:39.722Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}