{"record":{"id":"6f2abed883d2123e","repo":"apache/seatunnel","slug":"could-not-load-keystore","errorCode":null,"errorMessage":"Could not load keystore","messagePattern":"Could not load keystore","errorType":"exception","errorClass":"DebeziumException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-cdc/connector-cdc-mysql/src/main/java/io/debezium/connector/mysql/MySqlStreamingChangeEventSource.java","lineNumber":1296,"sourceCode":"                            + connectorConfig.getLogicalName());\n\n            final char[] keyPasswordArray = connection.connectionConfig().sslKeyStorePassword();\n            final String keyFilename = connection.connectionConfig().sslKeyStore();\n            final char[] trustPasswordArray = connection.connectionConfig().sslTrustStorePassword();\n            final String trustFilename = connection.connectionConfig().sslTrustStore();\n            KeyManager[] keyManagers = null;\n            if (keyFilename != null) {\n                try {\n                    KeyStore ks = connection.loadKeyStore(keyFilename, keyPasswordArray);\n\n                    KeyManagerFactory kmf = KeyManagerFactory.getInstance(\"NewSunX509\");\n                    kmf.init(ks, keyPasswordArray);\n\n                    keyManagers = kmf.getKeyManagers();\n                } catch (KeyStoreException\n                        | NoSuchAlgorithmException\n                        | UnrecoverableKeyException e) {\n                    throw new DebeziumException(\"Could not load keystore\", e);\n                }\n            }\n            TrustManager[] trustManagers;\n            try {\n                KeyStore ks = null;\n                if (trustFilename != null) {\n                    ks = connection.loadKeyStore(trustFilename, trustPasswordArray);\n                }\n\n                if (ks == null && (sslMode == SSLMode.PREFERRED || sslMode == SSLMode.REQUIRED)) {\n                    trustManagers =\n                            new TrustManager[] {\n                                new X509TrustManager() {\n\n                                    @Override\n                                    public void checkClientTrusted(\n                                            X509Certificate[] x509Certificates, String s)\n                                            throws CertificateException {}","sourceCodeStart":1278,"sourceCodeEnd":1314,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-cdc/connector-cdc-mysql/src/main/java/io/debezium/connector/mysql/MySqlStreamingChangeEventSource.java#L1278-L1314","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"// before\n\"ssl-mode\" = \"identity_verification\",\n\"keystore-file\" = \"/wrong/path/keystore.jks\",\n\"keystore-passwd\" = \"wrongpass\"\n// after\n\"ssl-mode\" = \"identity_verification\",\n\"keystore-file\" = \"/etc/seatunnel/keystore.p12\",\n\"keystore-passwd\" = \"correctpass\"","handlingStrategy":"validation","validationCode":"// Validate the keystore loads and contains a private key BEFORE starting the job\nKeyStore ks = KeyStore.getInstance(\"PKCS12\");\ntry (InputStream in = new FileInputStream(keystorePath)) {\n    ks.load(in, keystorePassword.toCharArray());\n}\nboolean hasKey = java.util.Collections.list(ks.aliases()).stream()\n    .anyMatch(a -> {\n        try { return ks.isKeyEntry(a); } catch (KeyStoreException e) { return false; }\n    });\nif (!hasKey) throw new IllegalStateException(\"keystore has no private key entry\");","typeGuard":null,"tryCatchPattern":"try {\n    startCdcSource(config);\n} catch (DebeziumException e) {\n    if (\"Could not load keystore\".equals(e.getMessage())) {\n        log.error(\"Client keystore invalid: path, password, or type wrong\", e.getCause());\n        throw new FatalConfigException(\"Fix keystore-file/keystore-passwd in CDC config\", e);\n    }\n    throw e;\n}","preventionTips":["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."],"tags":["mysql","cdc","ssl","tls","keystore"],"backgroundTag":"file-read-failed","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}