elastic/elasticsearch · error · SslConfigException
could not load ssl private key file [{}]
Error message
could not load ssl private key file [{}] What it means
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.
Source
Thrown at libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/PemKeyConfig.java:124
}
final Certificate leafCertificate = certificates.get(0);
if (leafCertificate instanceof X509Certificate x509Certificate) {
return List.of(Tuple.tuple(getPrivateKey(keyPath), x509Certificate));
} else {
return List.of();
}
}
@Override
public SslTrustConfig asTrustConfig() {
return new PemTrustConfig(List.of(certificate), configBasePath);
}
private PrivateKey getPrivateKey(Path path) {
try {
final PrivateKey privateKey = PemUtils.parsePrivateKey(path, () -> keyPassword);
if (privateKey == null) {
throw new SslConfigException("could not load ssl private key file [" + path + "]");
}
return privateKey;
} catch (SecurityException e) {
throw SslFileUtil.accessControlFailure(KEY_FILE_TYPE, List.of(path), e, configBasePath);
} catch (IOException e) {
throw SslFileUtil.ioException(KEY_FILE_TYPE, List.of(path), e, null, configBasePath);
} catch (GeneralSecurityException e) {
throw SslFileUtil.securityException(KEY_FILE_TYPE, List.of(path), e);
}
}
private List<Certificate> getCertificates(Path path) {
try {
return PemUtils.readCertificates(Collections.singleton(path));
} catch (SecurityException e) {
throw SslFileUtil.accessControlFailure(CERT_FILE_TYPE, List.of(path), e, configBasePath);
} catch (IOException e) {
throw SslFileUtil.ioException(CERT_FILE_TYPE, List.of(path), e, null, configBasePath);View on GitHub (pinned to db6a809a66)
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`.
Example fix
# before: OpenSSH private key fed to PemKeyConfig # key: id_ed25519 (BEGIN OPENSSH PRIVATE KEY) # after: convert to PKCS#8 PEM ssh-keygen -e -m PKCS8 -f id_ed25519 > id_ed25519.pub openssl pkey -in id_ed25519 -out id_ed25519.pem # now configure key: id_ed25519.pem
Defensive patterns
Strategy: validation
Validate before calling
// Confirm the file is a recognised private-key PEM before configuring it.
public static boolean looksLikePrivateKeyPem(Path p) throws IOException {
try (BufferedReader r = Files.newBufferedReader(p, StandardCharsets.UTF_8)) {
String line;
while ((line = r.readLine()) != null) {
if (line.startsWith("-----BEGIN")) {
return line.contains("PRIVATE KEY") || line.contains("DSA PARAMETERS") || line.contains("EC PARAMETERS");
}
}
}
return false;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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-----`).
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Error parsing Private Key [{}], file is empty
- cannot read encrypted key [{}] without a password
- failed to load a KeyManager for certificate/key pair [{}], [
- cannot create trust using PEM certificates [{}]
- could not load ssl private key file [{}]
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/4b43648eb6ce1d0c.
Report an issue: GitHub.