{"record":{"id":"99ab3b4243657847","repo":"elastic/elasticsearch","slug":"the-keystoretype-keystore-path-does-not-con","errorCode":null,"errorMessage":"the ${keystoreType} keystore [${path}]does not contain a private key entry","messagePattern":"the (.+?) keystore \\[(.+?)\\]does not contain a private key entry","errorType":"validation","errorClass":"SslConfigException","httpStatus":null,"severity":"error","filePath":"libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/StoreKeyConfig.java","lineNumber":206,"sourceCode":"    }\n\n    /**\n     * Verifies that the keystore contains at least 1 private key entry.\n     */\n    private static void checkKeyStore(KeyStore keyStore, Path path) throws KeyStoreException {\n        Enumeration<String> aliases = keyStore.aliases();\n        while (aliases.hasMoreElements()) {\n            String alias = aliases.nextElement();\n            if (keyStore.isKeyEntry(alias)) {\n                return;\n            }\n        }\n        String message = \"the \" + keyStore.getType() + \" keystore\";\n        if (path != null) {\n            message += \" [\" + path + \"]\";\n        }\n        message += \"does not contain a private key entry\";\n        throw new SslConfigException(message);\n    }\n\n    @Override\n    public String toString() {\n        final StringBuilder sb = new StringBuilder(getClass().getSimpleName());\n        sb.append('{');\n\n        String path = keystorePath;\n        if (path != null) {\n            sb.append(\"path=\").append(path).append(\", \");\n        }\n        sb.append(\"type=\").append(type);\n        sb.append(\", storePassword=\").append(storePassword.length == 0 ? \"<empty>\" : \"<non-empty>\");\n        sb.append(\", keyPassword=\");\n        if (keyPassword.length == 0) {\n            sb.append(\"<empty>\");\n        } else if (Arrays.equals(storePassword, keyPassword)) {\n            sb.append(\"<same-as-store-password>\");","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/StoreKeyConfig.java#L188-L224","documentation":"A keystore configured as the source of a private key (StoreKeyConfig) loaded successfully but contained no PrivateKey entries. The code walks every alias via keyStore.isKeyEntry(alias) and, if none qualifies, throws. Without a key entry the keystore cannot present a client or server identity during the TLS handshake.","triggerScenarios":"Constructing StoreKeyConfig for a keystore whose aliases are all trustedCertificateEntry (or empty). The configured keystore.path / keystore.type is loaded, then the alias scan runs and finds no key entry. The message interpolates keystoreType and the path (path is omitted from the bracketed segment when null).","commonSituations":"Pointed keystore.path at a truststore that only contains CA certs; created the keystore with keytool -genkey missing or with -importcert instead of importing the key; the private key lives in a PKCS#12 exported from a browser but the wrong file was referenced; keystore.password unlocks a different file.","solutions":["Run keytool -list -keystore <path> -v and confirm at least one alias is a PrivateKeyEntry","If this file is meant to verify peers (not present identity), move it to the truststore configuration instead of the keystore/key configuration","Regenerate the keystore so it contains the private key and its certificate chain (e.g. openssl pkcs12 -export -in cert.pem -inkey key.pem -out node.jks -chain -CAfile ca.pem)","Check that keystore.type (jks/pkcs12) matches the actual file format"],"exampleFix":"// before: file only holds trusted certs\nkeytool -list -keystore node.jks  # => trustedCertEntry, no PrivateKeyEntry\n// after: regenerate with the private key\nopenssl pkcs12 -export -in node.crt -inkey node.key -out node.p12 -chain -CAfile ca.pem","handlingStrategy":"validation","validationCode":"KeyStore ks = KeyStore.getInstance(type);\ntry (InputStream in = Files.newInputStream(path)) {\n    ks.load(in, password);\n}\nboolean hasKey = Collections.list(ks.aliases()).stream().anyMatch(ks::isKeyEntry);\nif (!hasKey) throw new IllegalStateException(\"keystore has no private key entry: \" + path);","typeGuard":"static boolean keystoreHasKeyEntry(KeyStore ks) throws KeyStoreException {\n    return Collections.list(ks.aliases()).stream().anyMatch(ks::isKeyEntry);\n}","tryCatchPattern":"try {\n    new StoreKeyConfig(...);\n} catch (SslConfigException e) {\n    // re-create keystore with a PrivateKeyEntry before retrying\n    throw e;\n}","preventionTips":["Validate keystore contents in a deploy script before node start","Keep a preflight check: keytool -list | grep PrivateKeyEntry","Never swap keystore and truststore paths without re-validating"],"tags":["ssl","keystore","config","security","startup"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}