apache/cassandra · error · PreparedQueryNotFoundException

Prepared query with ID %s not found (either the query was no

Error message

Prepared query with ID %s not found (either the query was not prepared on this host (maybe the host has been restarted?) or you have prepared too many queries and it has been evicted from the internal cache)

What it means

An EXECUTE message references a prepared statement id that is not in this node's prepared-statement cache; handler.getPrepared(statementId) returned null so Cassandra throws PreparedQueryNotFoundException. The id was never prepared on this host, the host was restarted (in-memory cache lost), or the entry was evicted from the bounded cache.

Source

Thrown at src/java/org/apache/cassandra/transport/messages/ExecuteMessage.java:140

        return true;
    }

    @Override
    protected boolean isTrackable()
    {
        return true;
    }

    @Override
    protected Message.Response execute(QueryState state, Dispatcher.RequestTime requestTime, boolean traceRequest)
    {
        QueryHandler.Prepared prepared = null;
        try
        {
            QueryHandler handler = ClientState.getCQLQueryHandler();
            prepared = handler.getPrepared(statementId);
            if (prepared == null)
                throw new PreparedQueryNotFoundException(statementId);

            if (!prepared.fullyQualified && prepared.statement.eligibleAsPreparedStatement() && !Objects.equals(state.getClientState().getRawKeyspace(), prepared.keyspace))
            {
                state.getClientState().warnAboutUseWithPreparedStatements(statementId, prepared.keyspace);

                String msg = String.format("Tried to execute a prepared unqualified statement on a keyspace it was not prepared on. " +
                                           " Executing the resulting prepared statement will return unexpected results: %s (on keyspace %s, previously prepared on %s)",
                                           statementId, state.getClientState().getRawKeyspace(), prepared.keyspace);
                nospam.error(msg);
            }

            CQLStatement statement = prepared.statement;
            options.prepare(statement.getBindVariables());

            if (options.getPageSize() == 0)
                throw new ProtocolException("The page size cannot be 0");

            if (traceRequest)

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Re-issue PREPARE for the original CQL string and retry the execution (drivers do this transparently — keep the driver current)
  2. Enable the driver's reprepare-on-up/reconnect behavior so prepares are replayed after topology or restart events
  3. Do not persist or share prepared statement ids across sessions/restarts; treat them as ephemeral
  4. Reduce distinct prepared statement count if eviction pressure is high

Example fix

// before
session.execute(preparedId, values); // stale id after restart
// after
try {
    session.execute(preparedId, values);
} catch (PreparedQueryNotFound e) {
    PreparedStatement ps = session.prepare(cql);
    session.execute(ps, values);
}
Defensive patterns

Strategy: retry

Validate before calling

if (!session.getPreparedIds().contains(statementId)) {
    PreparedStatement ps = session.prepare(cql);
    statementId = ps.getPreparedId();
}

Try / catch

try {
    session.execute(preparedId, values);
} catch (PreparedQueryNotFoundException e) {
    PreparedStatement ps = session.prepare(cql);
    session.execute(ps.bind(values));
}

Prevention

When it happens

Trigger: Sending ExecuteMessage with a statementId not present in the QueryHandler cache — node restart, prepare sent to one node and execute routed to another, cache eviction under high statement cardinality, or client retaining ids from a previous cluster generation.

Common situations: Failover after a datacenter outage where clients resume with old ids; rolling upgrades/restarts evicting all prepared statements; applications storing prepared ids in persistent state; long-running workloads exceeding the prepared statement cache capacity.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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