{"record":{"id":"4b43648eb6ce1d0c","repo":"elastic/elasticsearch","slug":"could-not-load-ssl-private-key-file","errorCode":null,"errorMessage":"could not load ssl private key file [{}]","messagePattern":"could not load ssl private key file \\[(.+?)\\]","errorType":"exception","errorClass":"SslConfigException","httpStatus":null,"severity":"error","filePath":"libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/PemKeyConfig.java","lineNumber":124,"sourceCode":"        }\n        final Certificate leafCertificate = certificates.get(0);\n        if (leafCertificate instanceof X509Certificate x509Certificate) {\n            return List.of(Tuple.tuple(getPrivateKey(keyPath), x509Certificate));\n        } else {\n            return List.of();\n        }\n    }\n\n    @Override\n    public SslTrustConfig asTrustConfig() {\n        return new PemTrustConfig(List.of(certificate), configBasePath);\n    }\n\n    private PrivateKey getPrivateKey(Path path) {\n        try {\n            final PrivateKey privateKey = PemUtils.parsePrivateKey(path, () -> keyPassword);\n            if (privateKey == null) {\n                throw new SslConfigException(\"could not load ssl private key file [\" + path + \"]\");\n            }\n            return privateKey;\n        } catch (SecurityException e) {\n            throw SslFileUtil.accessControlFailure(KEY_FILE_TYPE, List.of(path), e, configBasePath);\n        } catch (IOException e) {\n            throw SslFileUtil.ioException(KEY_FILE_TYPE, List.of(path), e, null, configBasePath);\n        } catch (GeneralSecurityException e) {\n            throw SslFileUtil.securityException(KEY_FILE_TYPE, List.of(path), e);\n        }\n    }\n\n    private List<Certificate> getCertificates(Path path) {\n        try {\n            return PemUtils.readCertificates(Collections.singleton(path));\n        } catch (SecurityException e) {\n            throw SslFileUtil.accessControlFailure(CERT_FILE_TYPE, List.of(path), e, configBasePath);\n        } catch (IOException e) {\n            throw SslFileUtil.ioException(CERT_FILE_TYPE, List.of(path), e, null, configBasePath);","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/PemKeyConfig.java#L106-L142","documentation":"Thrown by PemKeyConfig.getPrivateKey() when PemUtils.parsePrivateKey() returns null for the configured PEM key path. A null return means the file was read but did not contain any recognised private-key block, so no key material could be extracted.","triggerScenarios":"PemKeyConfig.getPrivateKey(Path) calls PemUtils.parsePrivateKey(path, passwordSupplier); the result is null. The parse loop scans for a '-----BEGIN' header; if none of the recognised formats (PKCS#1 RSA, PKCS#8, PKCS#8 encrypted, OpenSSL DSA, OpenSSL EC) is matched, parsePrivateKey throws a 'supported key format' error rather than returning null — so a null here typically indicates a parse failure inside a sub-parser that returned null unexpectedly, or a degenerate file.","commonSituations":"Empty key file, file containing only a public key, file containing only a certificate chain, or a file with an unrecognised PEM header (e.g. `-----BEGIN OPENSSH PRIVATE KEY-----`).","solutions":["Confirm the file contains a private key: `head -1 key.pem` should show a known header (e.g. `-----BEGIN PRIVATE KEY-----`).","Convert OpenSSH-format keys: `ssh-keygen -p -m PEM -f id_rsa` or `openssl pkey -in id_ed25519 -out ed25519.pem`.","If only a public key was supplied by mistake, generate or locate the matching private key.","Re-export in PKCS#8: `openssl pkcs8 -topk8 -inkey key.pem -out key.pk8.pem -nocrypt`."],"exampleFix":"# before: OpenSSH private key fed to PemKeyConfig\n# key: id_ed25519  (BEGIN OPENSSH PRIVATE KEY)\n\n# after: convert to PKCS#8 PEM\nssh-keygen -e -m PKCS8 -f id_ed25519 > id_ed25519.pub\nopenssl pkey -in id_ed25519 -out id_ed25519.pem\n# now configure key: id_ed25519.pem","handlingStrategy":"validation","validationCode":"// Confirm the file is a recognised private-key PEM before configuring it.\npublic static boolean looksLikePrivateKeyPem(Path p) throws IOException {\n    try (BufferedReader r = Files.newBufferedReader(p, StandardCharsets.UTF_8)) {\n        String line;\n        while ((line = r.readLine()) != null) {\n            if (line.startsWith(\"-----BEGIN\")) {\n                return line.contains(\"PRIVATE KEY\") || line.contains(\"DSA PARAMETERS\") || line.contains(\"EC PARAMETERS\");\n            }\n        }\n    }\n    return false;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Inspect the PEM header before configuring the file as a key.","Convert OpenSSH keys to PEM with ssh-keygen or openssl.","Use PKCS#8 (`openssl pkcs8 -topk8`) for maximum compatibility."],"tags":["ssl","pem","private-key","elasticsearch","crypto","config"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}