apache/cassandra · error · MarshalException

Invalid size for a counter context

Error message

Invalid size for a counter context

What it means

MarshalException raised by CounterContext.validateContext when a serialized counter context blob's size, after removing its header, is not a multiple of STEP_LENGTH. Counter contexts are sequences of fixed-size shards, so any other length means the bytes are corrupt or were not produced by the counter context serializer.

Source

Thrown at src/java/org/apache/cassandra/db/context/CounterContext.java:687

        accessor.putShort(cleared, 0, (short) globalShardIndexes.size());
        for (int i = 0; i < globalShardIndexes.size(); i++)
            accessor.putShort(cleared, HEADER_SIZE_LENGTH + i * HEADER_ELT_LENGTH, globalShardIndexes.get(i));

        int origHeaderLength = headerLength(context, accessor);
        accessor.copyTo(context,
                        origHeaderLength,
                        cleared,
                        accessor,
                        headerLength(cleared, accessor),
                        accessor.size(context) - origHeaderLength);

        return cleared;
    }

    public <V> void validateContext(V context, ValueAccessor<V> accessor) throws MarshalException
    {
        if ((accessor.size(context) - headerLength(context, accessor)) % STEP_LENGTH != 0)
            throw new MarshalException("Invalid size for a counter context");
    }

    /**
     * Returns the clock and the count associated with the local counter id, or (0, 0) if no such shard is present.
     */
    public ClockAndCount getLocalClockAndCount(ByteBuffer context)
    {
        return getClockAndCountOf(context, CounterId.getLocalId());
    }

    /**
     * Returns the count associated with the local counter id, or 0 if no such shard is present.
     */
    public long getLocalCount(ByteBuffer context)
    {
        return getLocalClockAndCount(context).count;
    }

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Repair/scrub the affected table (nodetool scrub) to drop or fix corrupt counter cells
  2. Restore the corrupted data from backup or an intact replica
  3. Ensure reads use the counter type, not a blob cast of unrelated bytes
Defensive patterns

Strategy: try-catch

Validate before calling

boolean validCounterContext(ByteBuffer buf) { return (buf.remaining() - CounterContext.instance().headerLength(buf)) % 16 == 0; }

Try / catch

try { CounterContext.instance().validateContext(ctx, accessor); } catch (MarshalException e) { repairOrScrub(keyspace, table); }

Prevention

When it happens

Trigger: Reading or validating a counter column whose serialized bytes were truncated, manually crafted, corrupted on disk, or produced by an incompatible/buggy writer.

Common situations: Corrupt SSTable or commit log segments, hand-editing serialized values, deserializing non-counter data as counters, data damage from failed hardware or bad migration tooling.

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