{"record":{"id":"dcffaba53ea095a3","repo":"apache/cassandra","slug":"an-hex-string-representing-bytes-must-have-an-even","errorCode":null,"errorMessage":"An hex string representing bytes must have an even length","messagePattern":"An hex string representing bytes must have an even length","errorType":"validation","errorClass":"NumberFormatException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/utils/Hex.java","lineNumber":66,"sourceCode":"                charToByte[c] = (byte)(c - '0');\n            else if (c >= 'A' && c <= 'F')\n                charToByte[c] = (byte)(c - 'A' + 10);\n            else if (c >= 'a' && c <= 'f')\n                charToByte[c] = (byte)(c - 'a' + 10);\n            else\n                charToByte[c] = (byte)-1;\n        }\n\n        for (int i = 0; i < 16; ++i)\n        {\n            byteToChar[i] = Integer.toHexString(i).charAt(0);\n        }\n    }\n\n    public static byte[] hexToBytes(String str)\n    {\n        if (str.length() % 2 == 1)\n            throw new NumberFormatException(\"An hex string representing bytes must have an even length\");\n\n        byte[] bytes = new byte[str.length() / 2];\n        for (int i = 0; i < bytes.length; i++)\n        {\n            byte halfByte1 = charToByte[str.charAt(i * 2)];\n            byte halfByte2 = charToByte[str.charAt(i * 2 + 1)];\n            if (halfByte1 == -1 || halfByte2 == -1)\n                throw new NumberFormatException(\"Non-hex characters in \" + str);\n            bytes[i] = (byte)((halfByte1 << 4) | halfByte2);\n        }\n        return bytes;\n    }\n\n    public static String bytesToHex(byte... bytes)\n    {\n        return bytesToHex(bytes, 0, bytes.length);\n    }\n","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/utils/Hex.java#L48-L84","documentation":"Hex.hexToBytes converts a hexadecimal string to a byte array. It throws NumberFormatException before parsing when the input string has an odd number of characters, because each byte requires exactly two hex digits and an odd-length string cannot represent whole bytes.","triggerScenarios":"Calling Hex.hexToBytes(str) with a string whose length % 2 == 1, e.g. 'abc' or '7f1'.","commonSituations":"Hand-written hex constants missing a digit; truncation when copying tokens/digests; concatenating hex fragments where a leading zero was dropped (e.g. 'f0a' instead of '0f0a').","solutions":["Check str.length() % 2 == 0 before calling hexToBytes and pad or reject the input","Pad odd-length input with a leading '0' if it represents a single nibble","Trace where the hex string is produced and fix the producer to always emit even-length output"],"exampleFix":"// before\nbyte[] bytes = Hex.hexToBytes(userHex);\n// after\nif (userHex.length() % 2 != 0)\n    userHex = \"0\" + userHex; // or reject\nbyte[] bytes = Hex.hexToBytes(userHex);","handlingStrategy":"validation","validationCode":"if (str == null || str.length() % 2 != 0) throw new IllegalArgumentException(\"hex string must have even length: \" + str);","typeGuard":null,"tryCatchPattern":"try { bytes = Hex.hexToBytes(str); } catch (NumberFormatException e) { /* reject or pad input */ }","preventionTips":["Validate hex input length and character set at system boundaries","Always produce hex via Hex.bytesToHex rather than hand-rolling","Add unit tests for odd-length and padded inputs"],"tags":["hex","parsing","input-validation"],"backgroundTag":"invalid-argument-format","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T21:17:11.552Z"}