{"record":{"id":"e5ab08ac02d820f6","repo":"elastic/elasticsearch","slug":"malformed-pem-file-ec-key-header-is-missing","errorCode":null,"errorMessage":"Malformed PEM file, EC Key header is missing","messagePattern":"Malformed PEM file, EC Key header is missing","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/PemUtils.java","lineNumber":185,"sourceCode":"     * Removes the EC Headers that OpenSSL adds to EC private keys as the information in them\n     * is redundant\n     *\n     * @throws IOException if the EC Parameter footer is missing\n     */\n    private static BufferedReader removeECHeaders(BufferedReader bReader) throws IOException {\n        String line = bReader.readLine();\n        while (line != null) {\n            if (OPENSSL_EC_PARAMS_FOOTER.equals(line.trim())) {\n                break;\n            }\n            line = bReader.readLine();\n        }\n        if (null == line || OPENSSL_EC_PARAMS_FOOTER.equals(line.trim()) == false) {\n            throw new IOException(\"Malformed PEM file, EC Parameters footer is missing\");\n        }\n        // Verify that the key starts with the correct header before passing it to parseOpenSslEC\n        if (OPENSSL_EC_HEADER.equals(bReader.readLine()) == false) {\n            throw new IOException(\"Malformed PEM file, EC Key header is missing\");\n        }\n        return bReader;\n    }\n\n    /**\n     * Removes the DSA Params Headers that OpenSSL adds to DSA private keys as the information in them\n     * is redundant\n     *\n     * @throws IOException if the EC Parameter footer is missing\n     */\n    private static BufferedReader removeDsaHeaders(BufferedReader bReader) throws IOException {\n        String line = bReader.readLine();\n        while (line != null) {\n            if (OPENSSL_DSA_PARAMS_FOOTER.equals(line.trim())) {\n                break;\n            }\n            line = bReader.readLine();\n        }","sourceCodeStart":167,"sourceCodeEnd":203,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/PemUtils.java#L167-L203","documentation":"Thrown by removeECHeaders immediately after the EC PARAMETERS footer has been located. It reads the next line and expects it to be '-----BEGIN EC PRIVATE KEY-----'; if it is null (EOF) or any other value, the PEM structure is broken. This protects parseOpenSslEC from receiving a reader positioned at the wrong place.","triggerScenarios":"An EC PARAMETERS block is followed by something other than an EC PRIVATE KEY block (e.g. a DSA PARAMETERS block pasted in by mistake, a certificate body, or EOF); the file has EC PARAMETERS but the EC PRIVATE KEY header was deleted or renamed to 'RSA PRIVATE KEY'.","commonSituations":"Concatenating PEM files incorrectly (e.g. appending an EC PARAMETERS block to an RSA key); copy-paste errors when assembling a combined PEM; a corrupted archive that merged unrelated blocks.","solutions":["Inspect the lines immediately after '-----END EC PARAMETERS-----' and confirm they begin with '-----BEGIN EC PRIVATE KEY-----'.","Regenerate the EC key cleanly with 'openssl ecparam -genkey -name prime256v1 -out ec-key.pem'.","If the EC PRIVATE KEY block lives in a separate file, point the config at that file rather than the parameters-only file."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// For a file starting with EC PARAMETERS, confirm the next non-blank line after the EC PARAMETERS footer is the EC PRIVATE KEY header\nstatic boolean ecParamsFollowedByEcKey(Path p) throws IOException {\n    try (BufferedReader r = Files.newBufferedReader(p, StandardCharsets.UTF_8)) {\n        String line; boolean sawParamsEnd = false;\n        while ((line = r.readLine()) != null) {\n            if (line.trim().equals(\"-----END EC PARAMETERS-----\")) sawParamsEnd = true;\n            else if (sawParamsEnd && line.trim().startsWith(\"-----BEGIN\")) {\n                return line.trim().equals(\"-----BEGIN EC PRIVATE KEY-----\");\n            }\n        }\n    }\n    return false;\n}","typeGuard":null,"tryCatchPattern":"try { PemUtils.readPrivateKey(path, passwordSupplier); }\ncatch (IOException e) { if (e.getMessage().contains(\"EC Key header is missing\")) { /* regenerate key */ } else throw e; }","preventionTips":["Do not concatenate unrelated PEM blocks into a single file.","Validate the structure with 'openssl ec -in <file> -noout' before deploying.","Keep EC PARAMETERS and EC PRIVATE KEY in the same file as generated by OpenSSL."],"tags":["ssl","pem","ec","config","private-key"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}