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_LOCALView on GitHub (pinned to 88fd0f6a0e)
Solutions
- Always provide an actual value for partition-key bind variables; never use unset() on them.
- Restructure code so statements with unset keys are not executed.
- 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
- Never call unset() on key columns
- Set all key bind markers unconditionally
- Review optional-binding code paths for key columns
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
- Key may not be empty
- Key length of %d is longer than maximum of %d
- Key may not be empty
- Key length of %d is longer than maximum of %d
- allowFilteringMessage(state)
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/d990ccbc760891e8.
Report an issue: GitHub.