{"record":{"id":"b68fb011ca49e6ce","repo":"apache/cassandra","slug":"a-cql-blob-string-must-have-an-even-length-since","errorCode":null,"errorMessage":"A CQL blob string must have an even length (since one byte is always 2 hexadecimal character)","messagePattern":"A CQL blob string must have an even length \\(since one byte is always 2 hexadecimal character\\)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/functions/types/utils/Bytes.java","lineNumber":145,"sourceCode":"    {\n        return toHexString(ByteBuffer.wrap(byteArray));\n    }\n\n    /**\n     * Parse an hex string representing a CQL blob.\n     *\n     * <p>The input should be a valid representation of a CQL blob, i.e. it must start by \"0x\"\n     * followed by the hexadecimal representation of the blob bytes.\n     *\n     * @param str the CQL blob string representation to parse.\n     * @return the bytes corresponding to {@code str}. If {@code str} is {@code null}, this method\n     * returns {@code null}.\n     * @throws IllegalArgumentException if {@code str} is not a valid CQL blob string.\n     */\n    public static ByteBuffer fromHexString(String str)\n    {\n        if ((str.length() & 1) == 1)\n            throw new IllegalArgumentException(\n            \"A CQL blob string must have an even length (since one byte is always 2 hexadecimal character)\");\n\n        if (str.charAt(0) != '0' || str.charAt(1) != 'x')\n            throw new IllegalArgumentException(\"A CQL blob string must start with \\\"0x\\\"\");\n\n        return ByteBuffer.wrap(fromRawHexString(str, 2));\n    }\n\n    /**\n     * Extract the content of the provided {@code ByteBuffer} as a byte array.\n     *\n     * <p>This method work with any type of {@code ByteBuffer} (direct and non-direct ones), but when\n     * the {@code ByteBuffer} is backed by an array, this method will try to avoid copy when possible.\n     * As a consequence, changes to the returned byte array may or may not reflect into the initial\n     * {@code ByteBuffer}.\n     *\n     * @param bytes the buffer whose content to extract.\n     * @return a byte array with the content of {@code bytes}. That array may be the array backing","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/functions/types/utils/Bytes.java#L127-L163","documentation":"Bytes.fromHexString converts a CQL blob literal string (0x-prefixed hex) into a ByteBuffer. Each byte requires exactly two hex characters, so an odd-length string cannot be a valid blob and this IllegalArgumentException is thrown before the prefix check. Note the odd-length check runs first, so an odd-length string reports this even if it also lacks '0x'.","triggerScenarios":"fromHexString(\"0xabc\") (3 nibbles), fromHexString(\"abc\") (odd length AND missing prefix), user input where a leading zero was stripped, manual string truncation.","commonSituations":"Display layers stripping leading zeros from hex values; hand-typed blob literals; clipboard/log truncation dropping the last hex char.","solutions":["Pad the string to even length (typically prefix a single '0'): \"0x0abc\".","Ensure the original value's full hex string is preserved end-to-end (avoid numeric parsing of hex strings).","Validate even length after the '0x' prefix before calling.","Generate blob strings with Bytes.toHexString(value) rather than hand-writing them."],"exampleFix":"// before\nByteBuffer bb = Bytes.fromHexString(\"0xabc\");\n// after\nByteBuffer bb = Bytes.fromHexString(\"0x0abc\"); // pad to even nibble count","handlingStrategy":"validation","validationCode":"String s = str.trim(); String hex = s.startsWith(\"0x\") ? s.substring(2) : s; if (hex.length() % 2 != 0) throw new IllegalArgumentException(\"odd hex length\");","typeGuard":null,"tryCatchPattern":"try { return Bytes.fromHexString(s); } catch (IllegalArgumentException e) { if (s.length() % 2 == 1) return Bytes.fromHexString(\"0x0\" + s.replaceFirst(\"^0x\", \"\")); throw e; }","preventionTips":["Treat blob strings as opaque strings, never as numbers","Round-trip via Bytes.toHexString/fromHexString pairs","Trim and validate format with regex ^0x([0-9a-fA-F]{2})+$"],"tags":["blob","hex","parsing"],"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"}