apache/cassandra · error · java.lang.IllegalArgumentException

Invalid number of components, expecting %d but got %d

Error message

Invalid number of components, expecting %d but got %d

What it means

ClusteringComparator.make() builds a Clustering from a varargs list of component values and enforces that the number of supplied values equals the number of clustering columns. This is an internal invariant check, thrown as IllegalArgumentException, typically a programming bug in internal code or tooling rather than a user-facing CQL error.

Source

Thrown at src/java/org/apache/cassandra/db/ClusteringComparator.java:125

        return clusteringTypes.get(i);
    }

    /**
     * Creates a row clustering based on the clustering values.
     * <p>
     * Every argument can either be a {@code ByteBuffer}, in which case it is used as-is, or a object
     * corresponding to the type of the corresponding clustering column, in which case it will be
     * converted to a byte buffer using the column type.
     *
     * @param values the values to use for the created clustering. There should be exactly {@code size()}
     * values which must be either byte buffers or of the type the column expect.
     *
     * @return the newly created clustering.
     */
    public Clustering<?> make(Object... values)
    {
        if (values.length != size())
            throw new IllegalArgumentException(String.format("Invalid number of components, expecting %d but got %d", size(), values.length));

        CBuilder builder = CBuilder.create(this);
        for (Object val : values)
        {
            if (val instanceof ByteBuffer)
                builder.add((ByteBuffer) val);
            else
                builder.add(val);
        }
        return builder.build();
    }

    public int compare(Clusterable c1, Clusterable c2)
    {
        return compare((ClusteringPrefix<?>) c1.clustering(), (ClusteringPrefix<?>) c2.clustering());
    }

    public <V1, V2> int compare(ClusteringPrefix<V1> c1, ClusteringPrefix<V2> c2)

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Pass exactly size() values (the table's clustering column count) to make().
  2. Derive the value count from the comparator/schema instead of hardcoding.
  3. Use CBuilder or the appropriate helper that handles partial clustering prefixes when applicable.

Example fix

// before
Clustering<?> c = comparator.make(partitionKeyValue); // table has 2 clustering columns
// after
Clustering<?> c = comparator.make(clusteringVal1, clusteringVal2);
Defensive patterns

Strategy: type-guard

Validate before calling

if (values.length != comparator.size())
    throw new IllegalArgumentException("Expected " + comparator.size() + " clustering components, got " + values.length);

Type guard

boolean hasValidArity(ClusteringComparator c, Object... vals) { return vals.length == c.size(); }

Try / catch

try { Clustering<?> cl = comparator.make(values); } catch (IllegalArgumentException e) { if (e.getMessage().contains("Invalid number of components")) deriveArityFromSchema(); else throw e; }

Prevention

When it happens

Trigger: Calling ClusteringComparator.make(v1, v2) on a table with a different number of clustering columns; programmatic row construction (compaction, repairs, tools, tests) with the wrong arity.

Common situations: Custom utilities/tests that hardcode clustering arity; schema changes adding clustering columns while old code still builds 1-component clusterings.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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