apache/cassandra · error · InvalidRequestException

Key length of %d is longer than maximum of %d

Error message

Key length of %d is longer than maximum of %d

What it means

validateKey() enforces that a partition key fits in an unsigned short length prefix (65535 bytes), because keys are written with ByteBufferUtil/ByteArrayUtil writeWithShortLength on the wire and in SSTables. Longer keys would corrupt the length-prefixed encoding.

Source

Thrown at src/java/org/apache/cassandra/cql3/QueryProcessor.java:297

    public Prepared getPrepared(MD5Digest id)
    {
        return preparedStatements.getIfPresent(id);
    }

    public static void validateKey(ByteBuffer key) throws InvalidRequestException
    {
        if (key == null || key.remaining() == 0)
        {
            throw new InvalidRequestException("Key may not be empty");
        }
        if (key == ByteBufferUtil.UNSET_BYTE_BUFFER)
            throw new InvalidRequestException("Key may not be unset");

        // check that key can be handled by ByteArrayUtil.writeWithShortLength and ByteBufferUtil.writeWithShortLength
        if (key.remaining() > FBUtilities.MAX_UNSIGNED_SHORT)
        {
            throw new InvalidRequestException("Key length of " + key.remaining() +
                                              " is longer than maximum of " + FBUtilities.MAX_UNSIGNED_SHORT);
        }
    }

    public ResultMessage processStatement(CQLStatement statement, QueryState queryState, QueryOptions options, Dispatcher.RequestTime requestTime)
    throws RequestExecutionException, RequestValidationException
    {
        logger.trace("Process {} @CL.{}", statement, options.getConsistency());
        ClientState clientState = queryState.getClientState();
        statement.authorize(clientState);
        statement.validate(clientState);

        ResultMessage result = options.getConsistency() == ConsistencyLevel.NODE_LOCAL
                             ? processNodeLocalStatement(statement, queryState, options)
                             : statement.execute(queryState, options, requestTime);

        return result == null ? new ResultMessage.Void() : result;
    }

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Reduce the key size (truncate, hash, or use a surrogate key) so it stays under 65535 bytes.
  2. Redesign the schema to use a smaller key with the large data moved to regular columns.
  3. Add application-side length validation on keys before binding.

Example fix

// before
stmt.bind(hugeBlob); // > 65535 bytes
// after
byte[] key = DigestUtils.sha256(hugeBlob); // fixed 32-byte surrogate key
stmt.bind(key);
Defensive patterns

Strategy: validation

Validate before calling

if (key.remaining() > 65535) throw new IllegalArgumentException("partition key exceeds 65535 bytes: " + key.remaining());

Try / catch

try { session.execute(stmt); } catch (InvalidRequestException e) { if (e.getMessage().startsWith("Key length of")) { /* hash or shrink key */ } }

Prevention

When it happens

Trigger: Binding a partition key whose serialized byte length exceeds FBUtilities.MAX_UNSIGNED_SHORT (65535 bytes), e.g. very large text/blob keys.

Common situations: Using huge composite keys or blob keys built from concatenated data; schema design without key-size limits; migrating from stores without such limits.

Understand the failure class

Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.

Related errors


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