apache/cassandra · error · IllegalArgumentException
A CQL blob string must have an even length (since one byte i
Error message
A CQL blob string must have an even length (since one byte is always 2 hexadecimal character)
What it means
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'.
Source
Thrown at src/java/org/apache/cassandra/cql3/functions/types/utils/Bytes.java:145
{
return toHexString(ByteBuffer.wrap(byteArray));
}
/**
* Parse an hex string representing a CQL blob.
*
* <p>The input should be a valid representation of a CQL blob, i.e. it must start by "0x"
* followed by the hexadecimal representation of the blob bytes.
*
* @param str the CQL blob string representation to parse.
* @return the bytes corresponding to {@code str}. If {@code str} is {@code null}, this method
* returns {@code null}.
* @throws IllegalArgumentException if {@code str} is not a valid CQL blob string.
*/
public static ByteBuffer fromHexString(String str)
{
if ((str.length() & 1) == 1)
throw new IllegalArgumentException(
"A CQL blob string must have an even length (since one byte is always 2 hexadecimal character)");
if (str.charAt(0) != '0' || str.charAt(1) != 'x')
throw new IllegalArgumentException("A CQL blob string must start with \"0x\"");
return ByteBuffer.wrap(fromRawHexString(str, 2));
}
/**
* Extract the content of the provided {@code ByteBuffer} as a byte array.
*
* <p>This method work with any type of {@code ByteBuffer} (direct and non-direct ones), but when
* the {@code ByteBuffer} is backed by an array, this method will try to avoid copy when possible.
* As a consequence, changes to the returned byte array may or may not reflect into the initial
* {@code ByteBuffer}.
*
* @param bytes the buffer whose content to extract.
* @return a byte array with the content of {@code bytes}. That array may be the array backingView on GitHub (pinned to 88fd0f6a0e)
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.
Example fix
// before
ByteBuffer bb = Bytes.fromHexString("0xabc");
// after
ByteBuffer bb = Bytes.fromHexString("0x0abc"); // pad to even nibble count Defensive patterns
Strategy: validation
Validate before calling
String s = str.trim(); String hex = s.startsWith("0x") ? s.substring(2) : s; if (hex.length() % 2 != 0) throw new IllegalArgumentException("odd hex length"); Try / catch
try { return Bytes.fromHexString(s); } catch (IllegalArgumentException e) { if (s.length() % 2 == 1) return Bytes.fromHexString("0x0" + s.replaceFirst("^0x", "")); throw e; } Prevention
- 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})+$
When it happens
Trigger: fromHexString("0xabc") (3 nibbles), fromHexString("abc") (odd length AND missing prefix), user input where a leading zero was stripped, manual string truncation.
Common situations: Display layers stripping leading zeros from hex values; hand-typed blob literals; clipboard/log truncation dropping the last hex char.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- A CQL blob string must start with "0x"
- Non-hex characters in <str>
- cannot parse '%s' as hex bytes
- cannot parse '%s' as hex bytes
- An hex string representing bytes must have an even length
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/b68fb011ca49e6ce.
Report an issue: GitHub.