apache/cassandra · error · MarshalException

String didn't validate.

Error message

String didn't validate.

What it means

MarshalException from UTF8Serializer.validate when UTF8Validator fails on the byte sequence: the bytes are not valid UTF-8 (illegal lead/trail bytes, overlong encodings, or truncated multi-byte sequences). Sentinels note the message carries no detail on purpose; the actual byte offsets are not reported.

Solutions

  1. Ensure the client encodes strings as UTF-8 (check character-set settings, avoid latin-1 or UTF-16 serialization)
  2. Sanitize input data before insert; use a text column with correct driver encoding
  3. If data arrived corrupted in transit, verify network/proxy layer is not re-encoding bytes
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at src/java/org/apache/cassandra/serializers/UTF8Serializer.java:39 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

Thrown at src/java/org/apache/cassandra/serializers/UTF8Serializer.java:39

import java.nio.charset.StandardCharsets;

import org.apache.cassandra.db.marshal.ByteArrayAccessor;
import org.apache.cassandra.db.marshal.ByteBufferAccessor;
import org.apache.cassandra.db.marshal.ValueAccessor;

public class UTF8Serializer extends AbstractTextSerializer
{
    public static final UTF8Serializer instance = new UTF8Serializer();

    protected UTF8Serializer()
    {
        super(StandardCharsets.UTF_8);
    }

    public <V> void validate(V value, ValueAccessor<V> accessor) throws MarshalException
    {
        if (!UTF8Validator.validate(value, accessor))
            throw new MarshalException("String didn't validate.");
    }

    static class UTF8Validator
    {
        enum State
        {
            START,
            TWO,
            TWO_80,
            THREE_a0bf,
            THREE_80bf_1,
            THREE_80bf_2,
            FOUR_90bf,
            FOUR_80bf_3,
        };

        // since we're not converting to java strings, we don't need to worry about converting to surrogates.
        // buf has already been sliced/duplicated.

View on GitHub (pinned to 88fd0f6a0e)