apache/cassandra · error · InvalidRequestException

Key may not be unset

Error message

Key may not be unset

What it means

validateKey() treats the special UNSET_BYTE_BUFFER sentinel as invalid for partition keys: an unset bind marker cannot be used as a key because the server cannot route a write/read with an unspecified key. It is thrown after the empty-key check.

Source

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

    public HashMap<MD5Digest, Prepared> getPreparedStatements()
    {
        return new HashMap<>(preparedStatements.asMap());
    }

    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

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Always provide an actual value for partition-key bind variables; never use unset() on them.
  2. Restructure code so statements with unset keys are not executed.
  3. Filter statements where key parameters are unset before execution.

Example fix

// before
BoundStatement bs = stmt.bind().unset("id"); // key unset
// after
BoundStatement bs = stmt.bind().setInt("id", userId);
Defensive patterns

Strategy: validation

Validate before calling

if (keyValue == UNSET) throw new IllegalStateException("partition key bind variable must be set, not unset");

Try / catch

try { bs = stmt.bind().setX("id", v); } catch (InvalidRequestException e) { if (e.getMessage().equals("Key may not be unset")) { /* ensure key set */ } }

Prevention

When it happens

Trigger: Binding a named parameter but not supplying its value (driver sends UNSET) for a partition-key column, e.g. stmt.bind("id", ... never set) or explicitly using unset() on a key variable in the driver.

Common situations: Using driver's unset()/UNSET sentinel for optional columns and accidentally applying it to the key; conditional code paths that skip setting the key parameter.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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