elastic/elasticsearch · error · IOException

Malformed PEM file, DEK-Info IV is invalid

Error message

Malformed PEM file, DEK-Info IV is invalid

What it means

Thrown by getCipherFromParameters when hexStringToByteArray raises IllegalArgumentException while converting the IV portion of the DEK-Info header to bytes. The IV must be a valid hex string; non-hex characters or incorrect casing for the radix trigger the underlying parse failure, which is wrapped in this IOException.

Source

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

     * @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");
        } else if ("AES-192-CBC".equals(algorithm)) {
            byte[] key = generateOpenSslKey(password, iv, 24);
            encryptionKey = new SecretKeySpec(key, "AES");
        } else if ("AES-256-CBC".equals(algorithm)) {
            byte[] key = generateOpenSslKey(password, iv, 32);
            encryptionKey = new SecretKeySpec(key, "AES");
        } else {
            throw new GeneralSecurityException("Private Key encrypted with unsupported algorithm [" + algorithm + "]");

View on GitHub (pinned to db6a809a66)

Solutions

  1. Inspect the IV portion after the comma in 'DEK-Info:' and confirm it contains only 0-9 and A-F/a-f characters.
  2. Regenerate the encrypted key with OpenSSL (the IV is generated automatically): 'openssl rsa -aes256 -in plain.key -out enc.key'.
  3. If the IV is unrecoverable, the key cannot be decrypted; regenerate it.
Defensive patterns

Strategy: validation

Validate before calling

// Validate the IV portion of DEK-Info is hexadecimal before invoking the parser
String ivString = /* IV token from DEK-Info */;
if (!ivString.matches("[0-9A-Fa-f]+")) {
    throw new IllegalArgumentException("DEK-Info IV is not hexadecimal: " + ivString);
}

Try / catch

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

Prevention

When it happens

Trigger: A DEK-Info IV containing non-hex characters (e.g. 'GHIJKL' or a typo), spaces, or a decimal value; an IV that was corrupted by a text-rewriting tool; manual editing that introduced an invalid character.

Common situations: Hand-edited PEM files; a templating system that mangled the hex; a copy-paste that replaced characters; an IV generated by non-conformant tooling.

Understand the failure class

Related errors


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