elastic/elasticsearch · error · IOException

Malformed PEM file, DEK-Info PEM header is invalid

Error message

Malformed PEM file, DEK-Info PEM header is invalid

What it means

Thrown by getCipherFromParameters when the DEK-Info header value does not split into exactly two comma-separated tokens (algorithm, IV). The expected format is e.g. 'AES-256-CBC,A1B2C3...'; a value with no comma, multiple commas, or an empty value is rejected before any cryptographic operation.

Source

Thrown at libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/PemUtils.java:506

    /**
     * Creates a {@link Cipher} from the contents of the DEK-Info header of a PEM file. RFC 1421 indicates that supported algorithms are
     * defined in RFC 1423. RFC 1423 only defines DES-CBS and triple DES (EDE) in CBC mode. AES in CBC mode is also widely used though ( 3
     * different variants of 128, 192, 256 bit keys )
     *
     * @param dekHeaderValue The value of the DEK-Info PEM header
     * @param password       The password with which the key is encrypted
     * @return a cipher of the appropriate algorithm and parameters to be used for decryption
     * @throws GeneralSecurityException if the algorithm is not available in the used security provider, or if the key is inappropriate
     * for the cipher
     * @throws IOException if the DEK-Info PEM header is invalid
     */
    private static Cipher getCipherFromParameters(String dekHeaderValue, char[] password) throws GeneralSecurityException, IOException {
        final String padding = "PKCS5Padding";
        final SecretKey encryptionKey;
        final String[] valueTokens = dekHeaderValue.split(",");
        if (valueTokens.length != 2) {
            throw new IOException("Malformed PEM file, DEK-Info PEM header is invalid");
        }
        final String algorithm = valueTokens[0];
        final String ivString = valueTokens[1];
        final byte[] iv;
        try {
            iv = hexStringToByteArray(ivString);
        } catch (IllegalArgumentException e) {
            throw new IOException("Malformed PEM file, DEK-Info IV is invalid", e);
        }
        if ("DES-CBC".equals(algorithm)) {
            byte[] key = generateOpenSslKey(password, iv, 8);
            encryptionKey = new SecretKeySpec(key, DEPRECATED_DES_ALGORITHM);
        } else if ("DES-EDE3-CBC".equals(algorithm)) {
            byte[] key = generateOpenSslKey(password, iv, 24);
            encryptionKey = new SecretKeySpec(key, DEPRECATED_DES_EDE_ALGORITHM);
        } else if ("AES-128-CBC".equals(algorithm)) {
            byte[] key = generateOpenSslKey(password, iv, 16);
            encryptionKey = new SecretKeySpec(key, "AES");

View on GitHub (pinned to db6a809a66)

Solutions

  1. Inspect the 'DEK-Info:' line and confirm it has exactly the form '<ALGO>,<HEX-IV>' with a single comma and no spaces.
  2. Regenerate the encrypted key with OpenSSL: 'openssl rsa -aes256 -in plain.key -out enc.key'.
  3. If you cannot recover the original IV, you cannot decrypt the key; regenerate it from scratch.
Defensive patterns

Strategy: validation

Validate before calling

// Validate the DEK-Info header has exactly two comma-separated tokens
String dek = /* extracted DEK-Info value */;
String[] tokens = dek.split(",");
if (tokens.length != 2) {
    throw new IllegalArgumentException("DEK-Info must be '<ALGO>,<HEX-IV>'");
}

Try / catch

try { PemUtils.readPrivateKey(path, passwordSupplier); }
catch (IOException e) { if (e.getMessage().contains("DEK-Info PEM header is invalid")) { /* fix header or regenerate */ } else throw e; }

Prevention

When it happens

Trigger: A DEK-Info header with only an algorithm and no IV, with extra commas, with whitespace inside tokens (the split does not trim the IV), or with a malformed value such as 'AES-256-CBC' alone; manual editing of the header; a sanitiser that rewrote the comma.

Common situations: Hand-edited or templated PEM files that altered the DEK-Info value; a copy-paste that lost the IV portion; a key produced by non-conformant tooling; locale-specific separators substituted for the comma.

Understand the failure class

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/3716a0d36deca0c1. Report an issue: GitHub.