apache/cassandra · error · InvalidRequestException
Key may not be empty
Error message
Key may not be empty
What it means
QueryProcessor.validateKey() rejects partition keys that are null or zero-length, because Cassandra cannot store or route rows with an empty partition key under the storage format used (short-length-prefixed keys). The check runs before executing any statement that carries a key.
Source
Thrown at src/java/org/apache/cassandra/cql3/QueryProcessor.java:289
preparedStatements.invalidate(id);
SystemKeyspace.removePreparedStatement(id);
}
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);View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Validate the partition key is non-empty before binding/executing the query.
- Fix upstream data or serialization code that produced an empty key.
- If a sentinel key is needed, use a non-empty value instead of an empty buffer.
Example fix
// before
byte[] key = new byte[0];
stmt.bind(key);
// after
if (keyBytes == null || keyBytes.length == 0) throw new IllegalArgumentException("key required");
stmt.bind(keyBytes); Defensive patterns
Strategy: validation
Validate before calling
if (key == null || key.remaining() == 0) throw new IllegalArgumentException("partition key must be non-empty"); Type guard
static boolean isValidKey(ByteBuffer k) { return k != null && k.remaining() > 0 && k != ByteBufferUtil.UNSET_BYTE_BUFFER && k.remaining() <= FBUtilities.MAX_UNSIGNED_SHORT; } Try / catch
try { session.execute(stmt); } catch (InvalidRequestException e) { if (e.getMessage().equals("Key may not be empty")) { /* fix key serialization */ } } Prevention
- Validate keys at API boundaries before binding
- Reject empty strings/byte arrays intended as keys upstream
- Unit-test key serialization paths
When it happens
Trigger: Calling validateKey / executing a statement whose partition key ByteBuffer is null or has remaining()==0, e.g. binding an empty byte[] or a empty string key.
Common situations: Application serializes an empty string/byte array as the partition key; deserialization produced a zero-length buffer; token-aware routing code extracting an empty key.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Key may not be empty
- Key length of %d is longer than maximum of %d
- Within a transaction, SELECT statements must select a single
- REVOKE operation is not supported by AllowAllAuthorizer
- Key may not be unset
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/bd3080a4e27835ea.
Report an issue: GitHub.