{"record":{"id":"051e6ec442d70eca","repo":"elastic/elasticsearch","slug":"malformed-pem-file-pem-footer-is-invalid-or-missi","errorCode":null,"errorMessage":"Malformed PEM file, PEM footer is invalid or missing","messagePattern":"Malformed PEM file, PEM footer is invalid or missing","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/PemUtils.java","lineNumber":234,"sourceCode":"     * PKCS#8\n     *\n     * @param bReader the {@link BufferedReader} containing the key file contents\n     * @return {@link PrivateKey}\n     * @throws IOException              if the file can't be read\n     * @throws GeneralSecurityException if the private key can't be generated from the {@link PKCS8EncodedKeySpec}\n     */\n    private static PrivateKey parsePKCS8(BufferedReader bReader) throws IOException, GeneralSecurityException {\n        StringBuilder sb = new StringBuilder();\n        String line = bReader.readLine();\n        while (line != null) {\n            if (PKCS8_FOOTER.equals(line.trim())) {\n                break;\n            }\n            sb.append(line.trim());\n            line = bReader.readLine();\n        }\n        if (null == line || PKCS8_FOOTER.equals(line.trim()) == false) {\n            throw new IOException(\"Malformed PEM file, PEM footer is invalid or missing\");\n        }\n        return parsePKCS8PemString(sb.toString());\n    }\n\n    /**\n     * Creates a {@link PrivateKey} from a String that contains the PEM encoded representation of a plaintext private key encoded in PKCS8\n     * @param pemString the PEM encoded representation of a plaintext private key encoded in PKCS8\n     * @return {@link PrivateKey}\n     * @throws IOException if the algorithm identifier can not be parsed from DER\n     * @throws GeneralSecurityException if the private key can't be generated from the {@link PKCS8EncodedKeySpec}\n     */\n    public static PrivateKey parsePKCS8PemString(String pemString) throws IOException, GeneralSecurityException {\n        byte[] keyBytes = Base64.getDecoder().decode(pemString);\n        String keyAlgo = getKeyAlgorithmIdentifier(keyBytes);\n        KeyFactory keyFactory = KeyFactory.getInstance(keyAlgo);\n        return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(keyBytes));\n    }\n","sourceCodeStart":216,"sourceCodeEnd":252,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/PemUtils.java#L216-L252","documentation":"Thrown by parsePKCS8 when, after the '-----BEGIN PRIVATE KEY-----' header, the scanner reaches EOF without finding '-----END PRIVATE KEY-----' or finds a different footer. The base64 body is collected line-by-line until the footer; absence of the footer means the key material is incomplete.","triggerScenarios":"A PKCS#8 PEM file whose '-----END PRIVATE KEY-----' line is missing, corrupted, or replaced by another marker; the file was truncated mid-body; the footer has trailing whitespace or CRLF that breaks the trimmed-equals check (note: line.trim() is applied, so plain spaces are tolerated but other invisible characters may not be).","commonSituations":"Truncated file from interrupted write or copy; templating system that strips END lines; an editor that auto-corrected the dash sequence; a file that was concatenating multiple keys and one was incomplete.","solutions":["Open the file and confirm both the BEGIN and END PRIVATE KEY markers are present and correctly spelled.","Regenerate the PKCS#8 key: 'openssl pkcs8 -topk8 -inkey raw.key -out pkcs8.key -nocrypt'.","Re-transfer the file in binary mode and verify checksums; strip stray characters with 'dos2unix' if the file came from Windows."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Confirm both the PKCS#8 BEGIN and END markers are present\nstatic boolean hasPkcs8Footer(Path p) throws IOException {\n    boolean begin = false, end = false;\n    try (BufferedReader r = Files.newBufferedReader(p, StandardCharsets.UTF_8)) {\n        String line;\n        while ((line = r.readLine()) != null) {\n            if (line.trim().equals(\"-----BEGIN PRIVATE KEY-----\")) begin = true;\n            if (line.trim().equals(\"-----END PRIVATE KEY-----\")) end = true;\n        }\n    }\n    return begin && end;\n}","typeGuard":null,"tryCatchPattern":"try { PemUtils.readPrivateKey(path, passwordSupplier); }\ncatch (IOException e) { if (e.getMessage().contains(\"PEM footer is invalid or missing\")) { /* re-issue key */ } else throw e; }","preventionTips":["Validate PEM files with 'openssl pkey -in <file> -noout' in CI.","Transfer in binary mode and verify checksums; run 'dos2unix' on Windows-sourced files.","Avoid stripping END lines via templating."],"tags":["ssl","pem","pkcs8","config","private-key"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}