apache/cassandra · error · InvalidTypeException

Invalid type for %s element, expecting %s but got %s

Error message

Invalid type for %s element, expecting %s but got %s

What it means

Thrown by TypeCodec's collection codecs when serializing a collection/list/set/map element fails because the element object is not an instance of the Java type the element codec expects. The codec catches the resulting ClassCastException and rethrows it as an InvalidTypeException naming the CQL type, the expected Java type, and the actual element class. This is the Java-driver-side guard ensuring collection elements match the declared CQL type before writing bytes.

Source

Thrown at src/java/org/apache/cassandra/cql3/functions/types/TypeCodec.java:2132

        public ByteBuffer serialize(C value, ProtocolVersion protocolVersion)
        {
            if (value == null) return null;
            int i = 0;
            ByteBuffer[] bbs = new ByteBuffer[value.size()];
            for (E elt : value)
            {
                if (elt == null)
                {
                    throw new NullPointerException("Collection elements cannot be null");
                }
                ByteBuffer bb;
                try
                {
                    bb = eltCodec.serialize(elt, protocolVersion);
                }
                catch (ClassCastException e)
                {
                    throw new InvalidTypeException(
                    String.format(
                    "Invalid type for %s element, expecting %s but got %s",
                    cqlType, eltCodec.getJavaType(), elt.getClass()),
                    e);
                }
                bbs[i++] = bb;
            }
            return CodecUtils.pack(bbs, value.size(), protocolVersion);
        }

        @Override
        public C deserialize(ByteBuffer bytes, ProtocolVersion protocolVersion)
        {
            if (bytes == null || bytes.remaining() == 0) return newInstance(0);
            try
            {
                ByteBuffer input = bytes.duplicate();
                int size = CodecUtils.readSize(input, protocolVersion);

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Fix the collection construction so every element is an instance of eltCodec.getJavaType() (e.g. use String elements for a list<text> column)
  2. Verify the column's CQL type in the schema and pick the matching codec via codecRegistry.codecFor(column.getType())
  3. Enable generics properly (avoid raw types) so javac catches the mismatch at compile time
  4. If the driver jar was rebuilt against a changed schema, recompile application code against the new types

Example fix

// before
List raw = new ArrayList();
raw.add(42); // column is list<text>
boundStatement.setList("tags", raw);
// after
List<String> tags = new ArrayList<>();
tags.add("42");
boundStatement.setList("tags", tags);
Defensive patterns

Strategy: type-guard

Validate before calling

// before serializing
Class<?> expected = codec.getJavaType().getRawType(); // for element codec: eltCodec.getJavaType()
for (Object elt : collection) {
    if (elt != null && !expected.isInstance(elt))
        throw new IllegalArgumentException("Element " + elt + " is not " + expected.getName());
}

Type guard

static <T> List<T> guardElements(Collection<?> c, Class<T> eltType) {
    for (Object o : c)
        if (o != null && !eltType.isInstance(o))
            throw new ClassCastException("Expected " + eltType + " but got " + o.getClass());
    return (List<T>) c;
}

Try / catch

try {
    bb = codec.serialize(value, protocolVersion);
} catch (InvalidTypeException e) {
    LOG.error("Element type mismatch: {}", e.getMessage(), e);
    throw new IllegalArgumentException("Fix collection element types before binding", e);
}

Prevention

When it happens

Trigger: Calling a collection codec's serialize() (e.g. via bound statement values, or TypeCodec<List<...>>.serialize directly) with a collection whose element is of the wrong Java class, e.g. putting an Integer into a List<String> column value with an unchecked cast, or a raw-typed collection after a CQL type change.

Common situations: Raw types or @SuppressWarnings casts hiding heterogeneous elements; schema changed the column's element type (int -> text) while code still builds old-typed collections; generic erasure letting Integer sneak into what was declared List<String>; using codec that doesn't match the actual statement metadata.

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/c95059af0e814918. Report an issue: GitHub.