apache/cassandra · error · InvalidRequestException

Prepared statement of size %d bytes is larger than allowed m

Error message

Prepared statement of size %d bytes is larger than allowed maximum of %d MB: %s...

What it means

When storing a prepared statement in the in-JVM prepared statements cache, Cassandra measures its serialized size and rejects statements larger than the configured cache size (cassandra.yaml prepared_statements_cache_size_mb). The statement is not cached and the client receives an InvalidRequestException with the statement's first 200 characters.

Source

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

    @VisibleForTesting
    private static ResultMessage.Prepared createResultMessage(MD5Digest statementId, Prepared existing)
    throws InvalidRequestException
    {
        ResultSet.PreparedMetadata preparedMetadata = ResultSet.PreparedMetadata.fromPrepared(existing.statement);
        ResultSet.ResultMetadata resultMetadata = ResultSet.ResultMetadata.fromPrepared(existing.statement);
        return new ResultMessage.Prepared(statementId, resultMetadata.getResultMetadataId(), preparedMetadata, resultMetadata);
    }

    @VisibleForTesting
    public static ResultMessage.Prepared storePreparedStatement(String queryString, String keyspace, Prepared prepared)
    throws InvalidRequestException
    {
        // Concatenate the current keyspace so we don't mix prepared statements between keyspace (#5352).
        // (if the keyspace is null, queryString has to have a fully-qualified keyspace so it's fine.
        MD5Digest statementId = computeId(queryString, keyspace);
        // don't execute the statement if it's bigger than the allowed threshold
        if (getSizeOfPreparedStatementForCache(statementId, prepared) > capacityToBytes(DatabaseDescriptor.getPreparedStatementsCacheSizeMiB()))
            throw new InvalidRequestException(String.format("Prepared statement of size %d bytes is larger than allowed maximum of %d MB: %s...",
                                                            prepared.pstmntSize,
                                                            DatabaseDescriptor.getPreparedStatementsCacheSizeMiB(),
                                                            queryString.substring(0, 200)));

        Prepared previous = preparedStatements.get(statementId, (ignored_) -> prepared);
        if (previous == prepared)
            SystemKeyspace.writePreparedStatement(keyspace, statementId, queryString, prepared.timestamp);

        ResultSet.PreparedMetadata preparedMetadata = ResultSet.PreparedMetadata.fromPrepared(prepared.statement);
        ResultSet.ResultMetadata resultMetadata = ResultSet.ResultMetadata.fromPrepared(prepared.statement);
        return new ResultMessage.Prepared(statementId, resultMetadata.getResultMetadataId(), preparedMetadata, resultMetadata);
    }

    @Override
    public ResultMessage processPrepared(CQLStatement statement,
                                         QueryState state,
                                         QueryOptions options,
                                         Map<String, ByteBuffer> customPayload,

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Increase prepared_statements_cache_size_mb in cassandra.yaml and restart
  2. Shorten the query: reduce IN-list size or number of bind markers
  3. Split the oversized statement into several smaller statements
  4. Ensure the cache size is not misconfigured (e.g. left at 0) in the environment

Example fix

// cassandra.yaml
// before
prepared_statements_cache_size_mb: 1
// after
prepared_statements_cache_size_mb: 16
Defensive patterns

Strategy: validation

Validate before calling

long maxBytes = DatabaseDescriptor.getPreparedStatementsCacheSizeMiB() * 1024L * 1024L;
if (queryString.length() > maxBytes / 16) log.warn("Statement may exceed prepared-statement cache budget: " + queryString.substring(0, 200));

Try / catch

try { session.prepare(bigQuery); } catch (InvalidRequestException e) { if (e.getMessage().startsWith("Prepared statement of size")) return splitStatement(bigQuery); throw e; }

Prevention

When it happens

Trigger: Preparing a CQL statement whose in-memory representation exceeds DatabaseDescriptor.getPreparedStatementsCacheSizeMiB() converted to bytes; common with huge IN clauses, thousands of markers, or when the cache size is set very small (or explicitly to 0/tiny value in tests).

Common situations: prepared_statements_cache_size_mb set to a small value in cassandra.yaml; schema with thousands of columns; dynamically generated queries with enormous IN lists; containers with tight heap where the cache was shrunk.

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