{"record":{"id":"f2ee3f159a660f44","repo":"alibaba/canal","slug":"can-t-encrypt-password-that-will-be-sent-to-mysql-f2ee3f","errorCode":null,"errorMessage":"can't encrypt password that will be sent to MySQL server.","messagePattern":"can't encrypt password that will be sent to MySQL server\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"critical","filePath":"driver/src/main/java/com/alibaba/otter/canal/parse/driver/mysql/packets/client/ClientAuthenticationPacket.java","lineNumber":73,"sourceCode":"        // feature\n\n        // 2. write max_packet_size\n        ByteHelper.writeUnsignedIntLittleEndian(MSC.MAX_PACKET_LENGTH, out);\n        // 3. write charset_number\n        out.write(this.charsetNumber);\n        // 4. write (filler) always 0x00...\n        out.write(new byte[23]);\n        // 5. write (Null-Terminated String) user\n        ByteHelper.writeNullTerminatedString(getUsername(), out);\n        // 6. write (Length Coded Binary) scramble_buff (1 + x bytes)\n        if (StringUtils.isEmpty(getPassword())) {\n            out.write(0x00);\n        } else {\n            try {\n                byte[] encryptedPassword = MySQLPasswordEncrypter.scramble411(getPassword().getBytes(), scrumbleBuff);\n                ByteHelper.writeBinaryCodedLengthBytes(encryptedPassword, out);\n            } catch (NoSuchAlgorithmException e) {\n                throw new RuntimeException(\"can't encrypt password that will be sent to MySQL server.\", e);\n            }\n        }\n        // 7 . (Null-Terminated String) databasename (optional)\n        if (getDatabaseName() != null) {\n            ByteHelper.writeNullTerminatedString(getDatabaseName(), out);\n        }\n        // 8 . (Null-Terminated String) auth plugin name (optional)\n        if (getAuthPluginName() != null) {\n            ByteHelper.writeNullTerminated(getAuthPluginName(), out);\n        }\n        // end write\n        return out.toByteArray();\n    }\n\n    public String getUsername() {\n        return username;\n    }\n","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/alibaba/canal/blob/87be50e87686a3e8af08c368d0e1ffd1f59eb04a/driver/src/main/java/com/alibaba/otter/canal/parse/driver/mysql/packets/client/ClientAuthenticationPacket.java#L55-L91","documentation":"Thrown by ClientAuthenticationPacket.toBytes() when MySQLPasswordEncrypter.scramble411 raises a NoSuchAlgorithmException during the legacy mysql_native_password (4.1) scramble. scramble411 relies on the SHA-1 MessageDigest. The error means the JVM does not provide SHA-1, which is extremely unusual for a stock JDK but can occur on a stripped/custom security provider or a JCE policy that removed SHA-1.","triggerScenarios":"Authenticating to MySQL with a non-empty password using the default ClientAuthenticationPacket (mysql_native_password path) on a JVM whose security configuration disabled the SHA-1 algorithm. Also reproducible if a custom Provider is installed that does not register SHA-1.","commonSituations":"Hardened/FIPS JVM that removes SHA-1; a minimal JRE in a container image that excluded sun security providers; java.security file edited to strip SHA-1 usage; running on an exotic JDK port.","solutions":["Confirm SHA-1 is available: MessageDigest.getInstance(\"SHA-1\") in a shell; if it fails, restore the default SunRsaSign/SunEC/Sun providers in java.security.","Remove or relax any java.security property (e.g. jdk.tls.disabledAlgorithms, Alg.Alias) that disables SHA-1.","If the environment legitimately forbids SHA-1, switch the MySQL account to caching_sha2_password and use ClientAuthenticationSHA2Packet instead.","Use a stock OpenJDK build for the Canal process rather than a stripped runtime."],"exampleFix":"// before\nMessageDigest.getInstance(\"SHA-1\"); // fails -> auth packet throws\n\n// after\n// verify provider registration\nfor (java.security.Provider p : java.security.Security.getProviders()) {\n    System.out.println(p);\n}\n// ensure java.security contains: security.provider.1=sun.security.provider.Sun\n// and SHA-1 is not in jdk.certpath.disabledAlgorithms for MessageDigest","handlingStrategy":"validation","validationCode":"public static boolean sha1Available() {\n    try { java.security.MessageDigest.getInstance(\"SHA-1\"); return true; }\n    catch (java.security.NoSuchAlgorithmException e) { return false; }\n}\n// before authenticating: if (!sha1Available()) fail fast with a clear message","typeGuard":null,"tryCatchPattern":"try {\n    packet.toBytes();\n} catch (RuntimeException e) {\n    if (e.getCause() instanceof java.security.NoSuchAlgorithmException) {\n        // report unsupported JVM / switch auth plugin\n    }\n    throw e;\n}","preventionTips":["Run Canal on a stock OpenJDK that ships SHA-1 support.","Verify java.security has not disabled SHA-1 in production images.","Prefer caching_sha2_password with the SHA2 packet on hardened JVMs, or use an empty password over TLS."],"tags":["authentication","mysql","security","sha1","jvm","crypto"],"backgroundTag":null,"analyzedSha":"87be50e87686a3e8af08c368d0e1ffd1f59eb04a","analyzedAt":"2026-08-14T04:30:11.918Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}