elastic/elasticsearch · error · IOException
Malformed PEM file, PEM footer is invalid or missing
Error message
Malformed PEM file, PEM footer is invalid or missing
What it means
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.
Source
Thrown at libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/PemUtils.java:234
* PKCS#8
*
* @param bReader the {@link BufferedReader} containing the key file contents
* @return {@link PrivateKey}
* @throws IOException if the file can't be read
* @throws GeneralSecurityException if the private key can't be generated from the {@link PKCS8EncodedKeySpec}
*/
private static PrivateKey parsePKCS8(BufferedReader bReader) throws IOException, GeneralSecurityException {
StringBuilder sb = new StringBuilder();
String line = bReader.readLine();
while (line != null) {
if (PKCS8_FOOTER.equals(line.trim())) {
break;
}
sb.append(line.trim());
line = bReader.readLine();
}
if (null == line || PKCS8_FOOTER.equals(line.trim()) == false) {
throw new IOException("Malformed PEM file, PEM footer is invalid or missing");
}
return parsePKCS8PemString(sb.toString());
}
/**
* Creates a {@link PrivateKey} from a String that contains the PEM encoded representation of a plaintext private key encoded in PKCS8
* @param pemString the PEM encoded representation of a plaintext private key encoded in PKCS8
* @return {@link PrivateKey}
* @throws IOException if the algorithm identifier can not be parsed from DER
* @throws GeneralSecurityException if the private key can't be generated from the {@link PKCS8EncodedKeySpec}
*/
public static PrivateKey parsePKCS8PemString(String pemString) throws IOException, GeneralSecurityException {
byte[] keyBytes = Base64.getDecoder().decode(pemString);
String keyAlgo = getKeyAlgorithmIdentifier(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(keyAlgo);
return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(keyBytes));
}
View on GitHub (pinned to db6a809a66)
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.
Defensive patterns
Strategy: validation
Validate before calling
// Confirm both the PKCS#8 BEGIN and END markers are present
static boolean hasPkcs8Footer(Path p) throws IOException {
boolean begin = false, end = false;
try (BufferedReader r = Files.newBufferedReader(p, StandardCharsets.UTF_8)) {
String line;
while ((line = r.readLine()) != null) {
if (line.trim().equals("-----BEGIN PRIVATE KEY-----")) begin = true;
if (line.trim().equals("-----END PRIVATE KEY-----")) end = true;
}
}
return begin && end;
} Try / catch
try { PemUtils.readPrivateKey(path, passwordSupplier); }
catch (IOException e) { if (e.getMessage().contains("PEM footer is invalid or missing")) { /* re-issue key */ } else throw e; } Prevention
- 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.
When it happens
Trigger: 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).
Common situations: 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.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- could not load ssl private key file [{}]
- Error parsing Private Key [{}], file is empty
- cannot read encrypted key [{}] without a password
- cannot read PEM private key [{}] because the file does not c
- Malformed PEM file, EC Parameters footer is missing
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/051e6ec442d70eca.
Report an issue: GitHub.