alibaba/canal · critical · IOException
can't encrypt password that will be sent to MySQL server.
Error message
can't encrypt password that will be sent to MySQL server.
What it means
Thrown by ClientAuthenticationSHA2Packet.toBytes() when MySQLPasswordEncrypter.scrambleCachingSha2 raises any Exception during the caching_sha2_password scramble (which uses SHA-256). Unlike the legacy packet (which only catches NoSuchAlgorithmException), this path catches a broad Exception, so the cause may be an unsupported SHA-256 algorithm, a null/empty scramble buffer, or a digest/encoding failure. Wrapped in an IOException.
Source
Thrown at driver/src/main/java/com/alibaba/otter/canal/parse/driver/mysql/packets/client/ClientAuthenticationSHA2Packet.java:48
// 2. write max_packet_size
ByteHelper.writeUnsignedIntLittleEndian(MSC.MAX_PACKET_LENGTH, out);
// 3. write charset_number
out.write(getCharsetNumber());
// 4. write (filler) always 0x00...
out.write(new byte[23]);
// 5. write (Null-Terminated String) user
ByteHelper.writeNullTerminatedString(getUsername(), out);
// 6. write (Length Coded Binary) scramble_buff (1 + x bytes)
if (StringUtils.isEmpty(getPassword())) {
out.write(0x00);
} else {
try {
byte[] encryptedPassword = MySQLPasswordEncrypter.scrambleCachingSha2(getPassword().getBytes(),
getScrumbleBuff());
ByteHelper.writeBinaryCodedLengthBytes(encryptedPassword, out);
} catch (Exception e) {
throw new IOException("can't encrypt password that will be sent to MySQL server.", e);
}
}
// 7 . (Null-Terminated String) databasename (optional)
if (getDatabaseName() != null) {
ByteHelper.writeNullTerminatedString(getDatabaseName(), out);
}
// 8 . (Null-Terminated String) auth plugin name (optional)
if (getAuthPluginName() != null) {
ByteHelper.writeNullTerminated(getAuthPluginName(), out);
}
// end write
return out.toByteArray();
}
}
View on GitHub (pinned to 87be50e876)
Solutions
- Inspect the chained cause in the IOException to distinguish missing-algorithm vs null-scramble cases.
- Ensure the server handshake packet is intact and scrumbleBuff is non-null before building the SHA2 packet.
- On a restricted JVM, re-enable SHA-256 in java.security or use a stock OpenJDK.
- If caching_sha2_password cannot be supported, change the MySQL user to mysql_native_password (error 322 path) or use an empty password over TLS.
- Upgrade the Canal driver to a version with the full caching_sha2_password RSA/CLS round-trip support.
Example fix
// before
byte[] enc = MySQLPasswordEncrypter.scrambleCachingSha2(pwd.getBytes(), scrumbleBuff);
// after
if (scrumbleBuff == null || scrumbleBuff.length == 0) {
throw new IllegalStateException("Server scramble buffer is null; handshake packet may be corrupt");
}
MessageDigest.getInstance("SHA-256"); // fail fast with a clear message if unsupported
byte[] enc = MySQLPasswordEncrypter.scrambleCachingSha2(pwd.getBytes(), scrumbleBuff); Defensive patterns
Strategy: validation
Validate before calling
public static boolean canScrambleSha2(byte[] nonce) {
try { java.security.MessageDigest.getInstance("SHA-256"); return nonce != null && nonce.length > 0; }
catch (java.security.NoSuchAlgorithmException e) { return false; }
} Try / catch
try {
sha2Packet.toBytes();
} catch (java.io.IOException e) {
Throwable c = e.getCause();
if (c instanceof java.security.NoSuchAlgorithmException) { /* SHA-256 unavailable */ }
else if (c instanceof NullPointerException) { /* null scramble buffer */ }
throw e;
} Prevention
- Inspect the server handshake to ensure scrumbleBuff is non-null before building the SHA2 packet.
- Confirm SHA-256 is registered on the JVM (especially FIPS builds).
- Keep the Canal driver current for full caching_sha2_password support.
When it happens
Trigger: Authenticating to MySQL 8.0+ with a non-empty password over the caching_sha2_password plugin while the JVM cannot perform SHA-256 scrambling, or when the scramble buffer (nonce) received from the server handshake is null/malformed.
Common situations: MySQL 8 default auth plugin (caching_sha2_password) against a FIPS JVM that disables SHA-256; corrupt handshake packet producing a null scrumbleBuff; a buggy intermediate proxy mangling the server greeting; JDK without the Sun provider.
Related errors
- can't encrypt password that will be sent to MySQL server.
- canal socketChannel netty not support ssl mode: {}
- Invalid destination path
- ERROR # The kafka kerberos configuration file does not exist
- Subscript pulsar consumer error
AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14).
Data as JSON: /api/errors/dcf06041db1931f6.
Report an issue: GitHub.