apache/cassandra · error · MarshalException

Expected a UTF-8 string, but got a

Error message

Expected a UTF-8 string, but got a %s: %s

What it means

UTF8Type.fromJSONObject only accepts JSON values that are strings; anything else (number, boolean, map, list) cannot be converted to a UTF-8 column value. The cast to (String) throws ClassCastException, which is translated into this MarshalException naming the actual runtime type and value received.

Solutions

  1. Quote the value so it parses as a JSON string before calling fromJSONObject
  2. String.valueOf(...) the value in application code before handing it to the type
  3. Verify the target column type; if the column should hold numbers, use Int32Type/LongType instead of UTF8Type

Example fix

// before
Object parsed = JSONValue.parse(raw); // 42 -> Long
term = utf8Type.fromJSONObject(parsed); // MarshalException
// after
if (!(parsed instanceof String)) parsed = String.valueOf(parsed);
term = utf8Type.fromJSONObject(parsed);
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(parsed instanceof String)) throw new IllegalArgumentException("UTF8 value must be a JSON string, got: " + parsed);

Type guard

function isString(v) { return typeof v === 'string'; } // Java: if (!(parsed instanceof String)) ...

Try / catch

try { term = utf8Type.fromJSONObject(parsed); } catch (MarshalException e) { /* coerce with String.valueOf(parsed) and retry */ }

Prevention

When it happens

Trigger: Calling fromJSONObject with a parsed JSON object that is not a String, e.g. passing Json.parse("123") (an Integer/Double), a Boolean, or a Map/List into UTF8Type.instance.fromJSONObject.

Common situations: CQL literal passed as bare number or boolean for a text/varchar column (e.g. INSERT ... VALUES (42) instead of '42'); JSON payload where a field arrives as a number/bool but the column is text; client drivers serializing unquoted scalars.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/db/marshal/UTF8Type.java:59

    private static final ByteBuffer MASKED_VALUE = instance.decompose("****");

    UTF8Type() {super(ComparisonType.BYTE_ORDER);} // singleton

    public ByteBuffer fromString(String source)
    {
        return decompose(source);
    }

    @Override
    public Term fromJSONObject(Object parsed) throws MarshalException
    {
        try
        {
            return new Constants.Value(fromString((String) parsed));
        }
        catch (ClassCastException exc)
        {
            throw new MarshalException(String.format(
                    "Expected a UTF-8 string, but got a %s: %s", parsed.getClass().getSimpleName(), parsed));
        }
    }

    @Override
    public String toJSONString(ByteBuffer buffer, ProtocolVersion protocolVersion)
    {
        try
        {
            return '"' + JsonUtils.quoteAsJsonString(ByteBufferUtil.string(buffer, StandardCharsets.UTF_8)) + '"';
        }
        catch (CharacterCodingException exc)
        {
            throw new AssertionError("UTF-8 value contained non-utf8 characters: ", exc);
        }
    }

    @Override

View on GitHub (pinned to 88fd0f6a0e)