apache/cassandra · error · IllegalArgumentException

A CQL blob string must start with "0x"

Error message

A CQL blob string must start with "0x"

What it means

Bytes.fromHexString requires the CQL blob literal form, which must start with the two characters '0x'. A string with any other prefix (or empty) throws this IllegalArgumentException. Because the even-length check precedes it, a valid-length string without '0x' reports this message.

Source

Thrown at src/java/org/apache/cassandra/cql3/functions/types/utils/Bytes.java:149

    /**
     * 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 backing
     * {@code bytes} if this can avoid a copy.
     */
    public static byte[] getArray(ByteBuffer bytes)
    {

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Prepend "0x" to the string before calling fromHexString.
  2. Use Bytes.fromRawHexString if you have bare hex without the prefix and that fits your flow.
  3. Normalize input: case does not matter, but the 0x prefix is mandatory.
  4. Centralize blob-string formatting through Bytes.toHexString so outputs are always 0x-prefixed.

Example fix

// before
ByteBuffer bb = Bytes.fromHexString("abcdef");
// after
ByteBuffer bb = Bytes.fromHexString("0xabcdef");
Defensive patterns

Strategy: validation

Validate before calling

if (!str.startsWith("0x")) throw new IllegalArgumentException("blob literal must start with 0x: " + str); // or normalize: str = "0x" + str

Try / catch

try { return Bytes.fromHexString(s); } catch (IllegalArgumentException e) { if (!s.startsWith("0x")) return Bytes.fromHexString("0x" + s); throw e; }

Prevention

When it happens

Trigger: fromHexString("abcdef"), passing a Base64 string or a plain byte-array hex dump without the CQL prefix, passing output of Integer.toHexString (no 0x).

Common situations: Interoperating with tools that emit bare hex (some log formatters) instead of CQL literals; converting from other languages' hex encodings; users pasting raw hex into configuration.

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


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/0359489f6b8321d9. Report an issue: GitHub.