{"record":{"id":"4a909c10284e37ae","repo":"elastic/elasticsearch","slug":"failed-to-parse-any-certificates-from","errorCode":null,"errorMessage":"failed to parse any certificates from [{}]","messagePattern":"failed to parse any certificates from \\[(.+?)\\]","errorType":"exception","errorClass":"SslConfigException","httpStatus":null,"severity":"error","filePath":"libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/PemUtils.java","lineNumber":692,"sourceCode":"        String oidString = parser.readAsn1Object().getOid();\n        return switch (oidString) {\n            case \"1.2.840.10040.4.1\" -> \"DSA\";\n            case \"1.2.840.113549.1.1.1\" -> \"RSA\";\n            case \"1.2.840.10045.2.1\" -> \"EC\";\n            default -> throw new GeneralSecurityException(\n                \"Error parsing key algorithm identifier. Algorithm with OID [\" + oidString + \"] is not supported\"\n            );\n        };\n    }\n\n    public static List<Certificate> readCertificates(Collection<Path> certPaths) throws CertificateException, IOException {\n        CertificateFactory certFactory = CertificateFactory.getInstance(\"X.509\");\n        List<Certificate> certificates = new ArrayList<>(certPaths.size());\n        for (Path path : certPaths) {\n            try (InputStream input = Files.newInputStream(path)) {\n                final Collection<? extends Certificate> parsed = certFactory.generateCertificates(input);\n                if (parsed.isEmpty()) {\n                    throw new SslConfigException(\"failed to parse any certificates from [\" + path.toAbsolutePath() + \"]\");\n                }\n                certificates.addAll(parsed);\n            }\n        }\n        return certificates;\n    }\n\n    private static String getAlgorithmNameFromOid(String oidString) throws GeneralSecurityException {\n        return switch (oidString) {\n            case \"1.2.840.10040.4.1\" -> \"DSA\";\n            case \"1.2.840.113549.1.1.1\" -> \"RSA\";\n            case \"1.2.840.10045.2.1\" -> \"EC\";\n            case \"1.3.14.3.2.7\" -> \"DES-CBC\";\n            case \"2.16.840.1.101.3.4.1.1\" -> \"AES-128_ECB\";\n            case \"2.16.840.1.101.3.4.1.2\" -> \"AES-128_CBC\";\n            case \"2.16.840.1.101.3.4.1.3\" -> \"AES-128_OFB\";\n            case \"2.16.840.1.101.3.4.1.4\" -> \"AES-128_CFB\";\n            case \"2.16.840.1.101.3.4.1.6\" -> \"AES-128_GCM\";","sourceCodeStart":674,"sourceCodeEnd":710,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/PemUtils.java#L674-L710","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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>'."],"exampleFix":"// before: certificate setting points at the private key\nxpack.security.transport.ssl.certificate: /etc/elasticsearch/certs/node.key\n// after: certificate setting points at the certificate PEM\nxpack.security.transport.ssl.certificate: /etc/elasticsearch/certs/node.crt.pem","handlingStrategy":"validation","validationCode":"// Before calling readCertificates, confirm the file is non-empty and contains at least one CERTIFICATE block\nstatic boolean hasCertificate(Path p) throws IOException {\n    try (BufferedReader r = Files.newBufferedReader(p, StandardCharsets.UTF_8)) {\n        String line; boolean sawCert = false;\n        while ((line = r.readLine()) != null) {\n            if (line.trim().equals(\"-----BEGIN CERTIFICATE-----\")) sawCert = true;\n            if (line.trim().equals(\"-----END CERTIFICATE-----\") && sawCert) return true;\n        }\n    }\n    return false;\n}\n// Also: if (Files.size(p) == 0) throw new IllegalArgumentException(\"certificate file is empty\");","typeGuard":null,"tryCatchPattern":"try { List<Certificate> certs = PemUtils.readCertificates(List.of(path)); }\ncatch (SslConfigException e) { if (e.getMessage().contains(\"failed to parse any certificates\")) { /* point at the cert file */ } else throw e; }","preventionTips":["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."],"tags":["ssl","pem","certificate","x509","config"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}