{"record":{"id":"5185b908893464a1","repo":"elastic/elasticsearch","slug":"hexadecimal-string-has-odd-length-and-cannot","errorCode":null,"errorMessage":"Hexadecimal string [{}] has odd length and cannot be converted to a byte array","messagePattern":"Hexadecimal string \\[(.+?)\\] has odd length and cannot be converted to a byte array","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/PemUtils.java","lineNumber":586,"sourceCode":"\n    /**\n     * Converts a hexadecimal string to a byte array\n     */\n    private static byte[] hexStringToByteArray(String hexString) {\n        int len = hexString.length();\n        if (len % 2 == 0) {\n            byte[] data = new byte[len / 2];\n            for (int i = 0; i < len; i += 2) {\n                final int k = Character.digit(hexString.charAt(i), 16);\n                final int l = Character.digit(hexString.charAt(i + 1), 16);\n                if (k == -1 || l == -1) {\n                    throw new IllegalStateException(\"String [\" + hexString + \"] is not hexadecimal\");\n                }\n                data[i / 2] = (byte) ((k << 4) + l);\n            }\n            return data;\n        } else {\n            throw new IllegalStateException(\n                \"Hexadecimal string [\" + hexString + \"] has odd length and cannot be converted to a byte array\"\n            );\n        }\n    }\n\n    /**\n     * Parses a DER encoded EC key to an {@link ECPrivateKeySpec} using a minimal {@link DerParser}\n     *\n     * @param keyBytes the private key raw bytes\n     * @return {@link ECPrivateKeySpec}\n     * @throws IOException if the DER encoded key can't be parsed\n     */\n    private static ECPrivateKeySpec parseEcDer(byte[] keyBytes) throws IOException, GeneralSecurityException {\n        DerParser parser = new DerParser(keyBytes);\n        DerParser.Asn1Object sequence = parser.readAsn1Object();\n        parser = sequence.getParser();\n        parser.readAsn1Object().getInteger(); // version\n        String keyHex = parser.readAsn1Object().getString();","sourceCodeStart":568,"sourceCodeEnd":604,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/PemUtils.java#L568-L604","documentation":"Thrown by hexStringToByteArray when the input string has an odd number of characters, which cannot be evenly split into byte pairs. It is an IllegalStateException (unchecked) and currently surfaces through the DEK-Info IV parsing path, where getCipherFromParameters catches IllegalArgumentException — note the mismatch means this specific odd-length case would propagate unwrapped if reached directly, but in practice the IV path triggers the even-length branch first.","triggerScenarios":"A hex string with odd length (e.g. a truncated IV missing one character, or an extra character appended); a DEK-Info IV whose length is not a multiple of two.","commonSituations":"Truncated IV from a partial copy-paste; a templating system that dropped or duplicated a character; manual editing that introduced an off-by-one.","solutions":["Inspect the hex string length and ensure it is even (each byte is two hex digits).","Regenerate the encrypted key with OpenSSL so the IV is complete and valid.","Pre-validate hex strings in your code before invoking the parser (see defense section)."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Reject odd-length hex strings explicitly before parsing\nString s = /* hex string */;\nif (s == null || s.length() % 2 != 0) {\n    throw new IllegalArgumentException(\"Hex string must have even length: \" + s);\n}","typeGuard":null,"tryCatchPattern":"try { PemUtils.readPrivateKey(path, passwordSupplier); }\ncatch (RuntimeException e) { if (e.getMessage().contains(\"odd length\")) { /* regenerate key */ } else throw e; }","preventionTips":["Never truncate hex IVs.","Regenerate encrypted keys to obtain complete IVs.","Pre-validate hex string length before invoking parsers."],"tags":["ssl","pem","hex","iv","validation"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}