apache/cassandra · error · MarshalException

Tuple value contains too many fields (expected %s, got %s)

Error message

Tuple value contains too many fields (expected %s, got %s)

What it means

TupleType.filterSortAndValidateElements validates a list of field buffers before binding them into a tuple value. If more field values are supplied than the tuple type declares (size()), it throws this MarshalException. Tuples in Cassandra have a fixed arity, so extra values cannot be stored.

Source

Thrown at src/java/org/apache/cassandra/db/marshal/TupleType.java:408

        return pack(Arrays.asList(components));
    }

    @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("Tuple value contains too many fields (expected %s, got %s)", size(), buffers.size()));

        for (int i = 0; i < buffers.size(); i++)
        {
            // Since A tuple 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 (buffer == unsetValue)
                throw new InvalidRequestException(String.format("Invalid unset value for tuple field number %d", i));
            type(i).validate(buffer, valueAccessor);
        }

        return buffers;
    }

    @Override
    public <V> String getString(V input, ValueAccessor<V> accessor)
    {

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Truncate or fix the value list to match the declared tuple arity
  2. Check the table schema (DESCRIBE / system_schema.columns) for the current tuple definition
  3. If the tuple needs more fields, ALTER the column type first, then insert
  4. Validate list length in application code before binding the statement

Example fix

// before
tupleType.filterSortAndValidateElements(fields); // fields.size() may exceed arity
// after
if (fields.size() > tupleType.size())
    fields = fields.subList(0, tupleType.size());
tupleType.filterSortAndValidateElements(fields);
Defensive patterns

Strategy: validation

Validate before calling

if (fields.size() > tupleType.size())
    throw new IllegalArgumentException("expected at most " + tupleType.size() + " fields, got " + fields.size());

Try / catch

try {
    tupleType.bind(fields);
} catch (MarshalException e) {
    throw new IllegalArgumentException("tuple arity mismatch: " + e.getMessage());
}

Prevention

When it happens

Trigger: Binding an INSERT/UPDATE with more literal elements than the tuple column's declared types (e.g. tuple<int,int> given 3 elements); calling bind/fromString-related paths with an oversized field list.

Common situations: Application builds the tuple programmatically from a variable-length list and appends extra elements; schema altered the tuple to fewer fields but client code still sends the old width.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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