apache/seatunnel · error · DebeziumException
Could not load keystore
Error message
Could not load keystore
What it means
Thrown when building the SSL socket factory for the MySQL binlog connection: loading the client keystore failed with KeyStoreException, NoSuchAlgorithmException, or UnrecoverableKeyException. The keystore file could not be read as a keystore, its type/algorithm is unavailable, or keys cannot be recovered with the given password.
Source
Thrown at seatunnel-connectors-v2/connector-cdc/connector-cdc-mysql/src/main/java/io/debezium/connector/mysql/MySqlStreamingChangeEventSource.java:1296
+ connectorConfig.getLogicalName());
final char[] keyPasswordArray = connection.connectionConfig().sslKeyStorePassword();
final String keyFilename = connection.connectionConfig().sslKeyStore();
final char[] trustPasswordArray = connection.connectionConfig().sslTrustStorePassword();
final String trustFilename = connection.connectionConfig().sslTrustStore();
KeyManager[] keyManagers = null;
if (keyFilename != null) {
try {
KeyStore ks = connection.loadKeyStore(keyFilename, keyPasswordArray);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509");
kmf.init(ks, keyPasswordArray);
keyManagers = kmf.getKeyManagers();
} catch (KeyStoreException
| NoSuchAlgorithmException
| UnrecoverableKeyException e) {
throw new DebeziumException("Could not load keystore", e);
}
}
TrustManager[] trustManagers;
try {
KeyStore ks = null;
if (trustFilename != null) {
ks = connection.loadKeyStore(trustFilename, trustPasswordArray);
}
if (ks == null && (sslMode == SSLMode.PREFERRED || sslMode == SSLMode.REQUIRED)) {
trustManagers =
new TrustManager[] {
new X509TrustManager() {
@Override
public void checkClientTrusted(
X509Certificate[] x509Certificates, String s)
throws CertificateException {}View on GitHub (pinned to cf67b549a7)
Solutions
- Verify the keystore file path is correct and readable by the SeaTunnel process.
- Confirm the keystore password (and key password) in the connector config match the one used at keytool creation time.
- Re-create or validate the keystore: keytool -list -v -keystore client-keystore.p12 to confirm it loads and has a private key entry.
- Regenerate with an explicit compatible type: keytool -genkeypair -keystore client-keystore.p12 -storetype PKCS12.
- If mutual TLS is not actually required, remove the keystore config and use a simpler SSL mode (e.g. disabled or required without client auth).
Example fix
// before "ssl-mode" = "identity_verification", "keystore-file" = "/wrong/path/keystore.jks", "keystore-passwd" = "wrongpass" // after "ssl-mode" = "identity_verification", "keystore-file" = "/etc/seatunnel/keystore.p12", "keystore-passwd" = "correctpass"
Defensive patterns
Strategy: validation
Validate before calling
// Validate the keystore loads and contains a private key BEFORE starting the job
KeyStore ks = KeyStore.getInstance("PKCS12");
try (InputStream in = new FileInputStream(keystorePath)) {
ks.load(in, keystorePassword.toCharArray());
}
boolean hasKey = java.util.Collections.list(ks.aliases()).stream()
.anyMatch(a -> {
try { return ks.isKeyEntry(a); } catch (KeyStoreException e) { return false; }
});
if (!hasKey) throw new IllegalStateException("keystore has no private key entry"); Try / catch
try {
startCdcSource(config);
} catch (DebeziumException e) {
if ("Could not load keystore".equals(e.getMessage())) {
log.error("Client keystore invalid: path, password, or type wrong", e.getCause());
throw new FatalConfigException("Fix keystore-file/keystore-passwd in CDC config", e);
}
throw e;
} Prevention
- Verify keystore files with keytool -list -v before every deployment.
- Use PKCS12 (widely supported) and record the store type alongside the path.
- Store keystore passwords in a secret manager, not plaintext configs; sync on rotation.
- Ensure the SeaTunnel process user has read permission on the keystore file.
- Test mTLS with openssl s_client -cert ... -key ... against MySQL before going live.
When it happens
Trigger: connectorConfig specifies a client keystore (database.keystore.file) for mutual TLS, and kmf.init()/getKeyManagers() fails while initializing the KeyManagerFactory — corrupt file, wrong keystore password, wrong keystore type, or unsupported algorithm.
Common situations: Keystore path typo or file missing/corrupt; wrong key password passed to the connector; keystore created with an algorithm/JCE provider not available in the SeaTunnel JVM; PKCS12 vs JKS type mismatch.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- Could not load truststore
- Error reading MySQL variables:
- Unexpected error while connecting to MySQL and looking at GT
- Unexpected error while connecting to MySQL and looking at gt
- Unexpected error while connecting to MySQL and looking at pr
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/6f2abed883d2123e.
Report an issue: GitHub.