{"record":{"id":"d990ccbc760891e8","repo":"apache/cassandra","slug":"key-may-not-be-unset","errorCode":null,"errorMessage":"Key may not be unset","messagePattern":"Key may not be unset","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/QueryProcessor.java","lineNumber":292,"sourceCode":"\n    public HashMap<MD5Digest, Prepared> getPreparedStatements()\n    {\n        return new HashMap<>(preparedStatements.asMap());\n    }\n\n    public Prepared getPrepared(MD5Digest id)\n    {\n        return preparedStatements.getIfPresent(id);\n    }\n\n    public static void validateKey(ByteBuffer key) throws InvalidRequestException\n    {\n        if (key == null || key.remaining() == 0)\n        {\n            throw new InvalidRequestException(\"Key may not be empty\");\n        }\n        if (key == ByteBufferUtil.UNSET_BYTE_BUFFER)\n            throw new InvalidRequestException(\"Key may not be unset\");\n\n        // check that key can be handled by ByteArrayUtil.writeWithShortLength and ByteBufferUtil.writeWithShortLength\n        if (key.remaining() > FBUtilities.MAX_UNSIGNED_SHORT)\n        {\n            throw new InvalidRequestException(\"Key length of \" + key.remaining() +\n                                              \" is longer than maximum of \" + FBUtilities.MAX_UNSIGNED_SHORT);\n        }\n    }\n\n    public ResultMessage processStatement(CQLStatement statement, QueryState queryState, QueryOptions options, Dispatcher.RequestTime requestTime)\n    throws RequestExecutionException, RequestValidationException\n    {\n        logger.trace(\"Process {} @CL.{}\", statement, options.getConsistency());\n        ClientState clientState = queryState.getClientState();\n        statement.authorize(clientState);\n        statement.validate(clientState);\n\n        ResultMessage result = options.getConsistency() == ConsistencyLevel.NODE_LOCAL","sourceCodeStart":274,"sourceCodeEnd":310,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/QueryProcessor.java#L274-L310","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nBoundStatement bs = stmt.bind().unset(\"id\"); // key unset\n// after\nBoundStatement bs = stmt.bind().setInt(\"id\", userId);","handlingStrategy":"validation","validationCode":"if (keyValue == UNSET) throw new IllegalStateException(\"partition key bind variable must be set, not unset\");","typeGuard":null,"tryCatchPattern":"try { bs = stmt.bind().setX(\"id\", v); } catch (InvalidRequestException e) { if (e.getMessage().equals(\"Key may not be unset\")) { /* ensure key set */ } }","preventionTips":["Never call unset() on key columns","Set all key bind markers unconditionally","Review optional-binding code paths for key columns"],"tags":["cql","partition-key","unset-value"],"backgroundTag":"missing-required-argument","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}