elastic/elasticsearch · error · SslConfigException
failed to parse any certificates from [{}]
Error message
failed to parse any certificates from [{}] What it means
Thrown by readCertificates when CertificateFactory.generateCertificates returns an empty collection for a given path. This is an SslConfigException (not a CertificateException) indicating the file exists and is readable but contains no parseable X.509 certificates — the file is empty, contains only a private key, holds non-PEM/non-DER content, or the cert body is corrupted.
Source
Thrown at libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/PemUtils.java:692
String oidString = parser.readAsn1Object().getOid();
return switch (oidString) {
case "1.2.840.10040.4.1" -> "DSA";
case "1.2.840.113549.1.1.1" -> "RSA";
case "1.2.840.10045.2.1" -> "EC";
default -> throw new GeneralSecurityException(
"Error parsing key algorithm identifier. Algorithm with OID [" + oidString + "] is not supported"
);
};
}
public static List<Certificate> readCertificates(Collection<Path> certPaths) throws CertificateException, IOException {
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
List<Certificate> certificates = new ArrayList<>(certPaths.size());
for (Path path : certPaths) {
try (InputStream input = Files.newInputStream(path)) {
final Collection<? extends Certificate> parsed = certFactory.generateCertificates(input);
if (parsed.isEmpty()) {
throw new SslConfigException("failed to parse any certificates from [" + path.toAbsolutePath() + "]");
}
certificates.addAll(parsed);
}
}
return certificates;
}
private static String getAlgorithmNameFromOid(String oidString) throws GeneralSecurityException {
return switch (oidString) {
case "1.2.840.10040.4.1" -> "DSA";
case "1.2.840.113549.1.1.1" -> "RSA";
case "1.2.840.10045.2.1" -> "EC";
case "1.3.14.3.2.7" -> "DES-CBC";
case "2.16.840.1.101.3.4.1.1" -> "AES-128_ECB";
case "2.16.840.1.101.3.4.1.2" -> "AES-128_CBC";
case "2.16.840.1.101.3.4.1.3" -> "AES-128_OFB";
case "2.16.840.1.101.3.4.1.4" -> "AES-128_CFB";
case "2.16.840.1.101.3.4.1.6" -> "AES-128_GCM";View on GitHub (pinned to db6a809a66)
Solutions
- Verify the file contains one or more '-----BEGIN CERTIFICATE-----' ... '-----END CERTIFICATE-----' blocks (or is a valid DER-encoded certificate).
- Regenerate or re-export the certificate: 'openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes'.
- Confirm the config points at the certificate file, not the key: e.g. xpack.security.transport.ssl.certificate.
- Check the file is non-empty: 'ls -l <file>' and 'head -1 <file>'.
Example fix
// before: certificate setting points at the private key xpack.security.transport.ssl.certificate: /etc/elasticsearch/certs/node.key // after: certificate setting points at the certificate PEM xpack.security.transport.ssl.certificate: /etc/elasticsearch/certs/node.crt.pem
Defensive patterns
Strategy: validation
Validate before calling
// Before calling readCertificates, confirm the file is non-empty and contains at least one CERTIFICATE block
static boolean hasCertificate(Path p) throws IOException {
try (BufferedReader r = Files.newBufferedReader(p, StandardCharsets.UTF_8)) {
String line; boolean sawCert = false;
while ((line = r.readLine()) != null) {
if (line.trim().equals("-----BEGIN CERTIFICATE-----")) sawCert = true;
if (line.trim().equals("-----END CERTIFICATE-----") && sawCert) return true;
}
}
return false;
}
// Also: if (Files.size(p) == 0) throw new IllegalArgumentException("certificate file is empty"); Try / catch
try { List<Certificate> certs = PemUtils.readCertificates(List.of(path)); }
catch (SslConfigException e) { if (e.getMessage().contains("failed to parse any certificates")) { /* point at the cert file */ } else throw e; } Prevention
- Adopt a naming convention '*.crt.pem' for certificates and '*.key.pem' for keys.
- Lint certificate files with 'openssl x509 -in <file> -noout' in CI.
- Confirm the config setting name maps to a certificate (e.g. xpack.*.certificate), not a key.
When it happens
Trigger: Pointing a certificate configuration at a file that contains no certificates (e.g. only a private key, a CSR, a CRL, plain text, or an empty file); a certificate file whose BEGIN/END CERTIFICATE markers were stripped; a DER file that is actually something else.
Common situations: Swapping the certificate and key arguments in xpack.ssl settings; pointing at an empty placeholder file; a templating system that stripped the PEM markers; a file that was truncated to zero bytes by a failed deployment; using a PEM that contains only the chain intermediates with the wrong filename.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to load a KeyManager for certificate/key pair [{}], [
- could not load ssl private key file [{}]
- cannot create trust using PEM certificates [{}]
- Error parsing Private Key [{}], file is empty
- cannot read encrypted key [{}] without a password
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/4a909c10284e37ae.
Report an issue: GitHub.