apache/cassandra · error · MarshalException
UDT value contained too many fields
Error message
UDT value contained too many fields (expected %s, got %s)
What it means
A UDT value must supply at most one value per declared field. During UserType construction / filterSortAndValidateElements, if the buffer list is longer than the number of fields, this MarshalException reports expected vs actual counts.
Solutions
- Trim the value list to exactly size() fields before constructing
- Refresh schema metadata so the client's UserType matches the server's definition
- Fix the literal/query so each field appears at most once
Example fix
// before List<ByteBuffer> values = ...; // 5 entries for a 4-field UDT Value v = new UserType.Value(udt, values); // MarshalException // after if (values.size() > udt.size()) values = values.subList(0, udt.size()); Value v = new UserType.Value(udt, values);
Defensive patterns
Strategy: validation
Validate before calling
if (values.size() > udt.size()) throw new IllegalArgumentException("UDT expects at most " + udt.size() + " fields, got " + values.size()); Type guard
boolean arityOk(List<?> vals, UserType udt) { return vals.size() <= udt.size(); } Try / catch
try { v = new UserType.Value(udt, buffers); } catch (MarshalException e) { throw new BindingException("too many values for UDT"); } Prevention
- Bind UDT fields by name, not position, when possible
- Refresh cluster schema metadata after UDT evolution
- Add arity assertions in serialization code
When it happens
Trigger: Building a UserType value ( UserType constructor or MultiElements.DelayedValue resolution) with more Term/bindings than the UDT declares; frozen UDT literals with duplicated fields.
Common situations: Driver or application code binding positional values to a UDT after the type gained fields (or with stale metadata showing fewer fields); INSERT USING JSON where the JSON has more entries than fields (that path usually errors earlier with unknown field); mixed cluster versions with divergent UDT definitions.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Cannot add new field
- Altering field types is no longer supported
- ANY ConsistencyLevel is only supported for writes
- Can only unset '" + name + "'
- Cannot add new field
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/8228a4cbcba59336.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/db/marshal/UserType.java:687
return serializer;
}
@Override
public List<ByteBuffer> filterSortAndValidateElements(List<ByteBuffer> buffers)
{
return filterSortAndValidateElements(buffers, ByteBufferUtil.UNSET_BYTE_BUFFER, ByteBufferAccessor.instance);
}
@Override
public List<byte[]> filterSortAndValidateElementsFromArrays(List<byte[]> buffers)
{
return filterSortAndValidateElements(buffers, ByteArrayUtil.UNSET_BYTE_ARRAY, ByteArrayAccessor.instance);
}
private <T> List<T> filterSortAndValidateElements(List<T> buffers, T unsetValue, ValueAccessor<T> valueAccessor)
{
if (buffers.size() > size())
throw new MarshalException(String.format("UDT value contained too many fields (expected %s, got %s)", size(), buffers.size()));
for (int i = 0; i < buffers.size(); i++)
{
// Since a frozen UDT value is always written in its entirety Cassandra can't preserve a pre-existing
// value by 'not setting' the new value. Reject the query.
T buffer = buffers.get(i);
if (buffer == null)
continue;
if (!isMultiCell() && buffer == unsetValue)
throw new MarshalException(String.format("Invalid unset value for field '%s' of user defined type %s", fieldNameAsString(i), getNameAsString()));
type(i).validate(buffer, valueAccessor);
}
return buffers;
}
@Override
public SchemaElementType elementType()View on GitHub (pinned to 88fd0f6a0e)