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

  1. Trim the value list to exactly size() fields before constructing
  2. Refresh schema metadata so the client's UserType matches the server's definition
  3. 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

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


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)