apache/cassandra · error · InvalidRequestException

Counters are not allowed inside tuples

Error message

Counters are not allowed inside tuples

What it means

InvalidRequestException from RawTuple.prepare: one of the element types in a tuple declaration is a counter type. Counters are only permitted in counter tables and cannot appear as tuple components; the prepare loop checks each element with isCounter() before building the TupleType.

Source

Thrown at src/java/org/apache/cassandra/cql3/CQL3Type.java:1092

            public RawTuple freeze()
            {
                return this;
            }

            @Override
            public void validate(ClientState state, String name)
            {
                for (CQL3Type.Raw t : types)
                    t.validate(state, name);
            }

            public CQL3Type prepare(String keyspace, Types udts) throws InvalidRequestException
            {
                List<AbstractType<?>> ts = new ArrayList<>(types.size());
                for (CQL3Type.Raw t : types)
                {
                    if (t.isCounter())
                        throw new InvalidRequestException("Counters are not allowed inside tuples");

                    ts.add(t.prepare(keyspace, udts).getType());
                }
                return new Tuple(new TupleType(ts));
            }

            public boolean isTuple()
            {
                return true;
            }

            public boolean referencesUserType(String name)
            {
                return types.stream().anyMatch(t -> t.referencesUserType(name));
            }

            @Override
            public String toString()

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Move the counter to its own top-level column and keep the tuple for non-counter fields
  2. Use bigint (snapshot value) in the tuple instead of counter and update it with read-modify-write if approximate values suffice
  3. Split into two columns: one tuple, one counter

Example fix

// before
CREATE TABLE t (id uuid PRIMARY KEY, info tuple<text, counter>);
// after
CREATE TABLE t (id uuid PRIMARY KEY, info tuple<text>, hits counter);
Defensive patterns

Strategy: validation

Validate before calling

boolean usesCounterInTuple(String cqlTypeDecl) {
    return cqlTypeDecl.toLowerCase().replaceAll("\\s+","").matches("tuple<.*counter.*");
}

Try / catch

try { session.execute(ddl); } catch (InvalidQueryException e) { if (e.getMessage().equals("Counters are not allowed inside tuples")) { /* split counter into its own column */ } else throw e; }

Prevention

When it happens

Trigger: Declaring a column like `tuple<int, counter>` in CREATE TABLE / ALTER TABLE, or using counter as a tuple field anywhere in type preparation.

Common situations: Trying to bundle a counter with metadata in one tuple column; accidental use of a counter-typed Raw inside tuple field lists.

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