{"record":{"id":"7fd2421c7374628d","repo":"apache/cassandra","slug":"non-hex-characters-in","errorCode":null,"errorMessage":"Non-hex characters in ","messagePattern":"Non-hex characters in ","errorType":"validation","errorClass":"NumberFormatException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/utils/Hex.java","lineNumber":74,"sourceCode":"\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\n    public static String bytesToHex(byte bytes[], int offset, int length)\n    {\n        char[] c = new char[length * 2];\n        for (int i = 0; i < length; i++)\n        {\n            int bint = bytes[i + offset];\n            c[i * 2] = byteToChar[(bint & 0xf0) >> 4];\n            c[1 + i * 2] = byteToChar[bint & 0x0f];","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/utils/Hex.java#L56-L92","documentation":"Hex.hexToBytes looks up each character in its charToByte table; invalid characters map to -1. If either nibble of a byte is not a hex character (0-9, a-f, A-F), it throws NumberFormatException naming the offending string.","triggerScenarios":"Calling Hex.hexToBytes(str) with a string of even length that contains any non-hex character, e.g. 'zz12', '12 34' (space), or '0x12'.","commonSituations":"Passing strings with 0x prefixes; whitespace or separator characters from formatted logs; copy-paste artifacts; non-ASCII characters from encoding mishaps.","solutions":["Validate the string matches ^[0-9a-fA-F]+$ before calling hexToBytes","Strip common decorations such as '0x' prefix, whitespace, and separators","Fix the upstream source that generated the corrupted hex string"],"exampleFix":"// before\nbyte[] bytes = Hex.hexToBytes(value.replace(\"0x\", \"\"));\n// after\nString hex = value.replace(\"0x\", \"\").trim();\nif (!hex.matches(\"[0-9a-fA-F]+\"))\n    throw new IllegalArgumentException(\"not hex: \" + hex);\nbyte[] bytes = Hex.hexToBytes(hex);","handlingStrategy":"validation","validationCode":"if (str == null || !str.matches(\"[0-9a-fA-F]+\")) throw new IllegalArgumentException(\"invalid hex: \" + str);","typeGuard":null,"tryCatchPattern":"try { bytes = Hex.hexToBytes(str); } catch (NumberFormatException e) { /* handle non-hex input */ }","preventionTips":["Strip 0x prefixes, whitespace, and separators before parsing","Validate with a hex regex at the input boundary","Keep hex strings in canonical lowercase form end-to-end"],"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"}