{"record":{"id":"5e129ba2ef6cbc23","repo":"apache/cassandra","slug":"key-may-not-be-empty-5e129b","errorCode":null,"errorMessage":"Key may not be empty","messagePattern":"Key may not be empty","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/Validation.java","lineNumber":49,"sourceCode":" * Note: this hosts functions that were historically in ThriftValidation, but\n * it's not necessary clear that this is the best place to have this (this is\n * certainly not horrible either though).\n */\npublic abstract class Validation\n{\n\n    /**\n     * Validates a (full serialized) partition key.\n     *\n     * @param metadata the metadata for the table of which to check the key.\n     * @param key the serialized partition key to check.\n     *\n     * @throws InvalidRequestException if the provided {@code key} is invalid.\n     */\n    public static void validateKey(TableMetadata metadata, ByteBuffer key)\n    {\n        if (key == null || key.remaining() == 0)\n            throw new InvalidRequestException(\"Key may not be empty\");\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 \" +\n                                              FBUtilities.MAX_UNSIGNED_SHORT);\n        }\n\n        try\n        {\n            metadata.partitionKeyType.validate(key);\n        }\n        catch (MarshalException e)\n        {\n            throw new InvalidRequestException(e.getMessage());\n        }\n    }","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/Validation.java#L31-L67","documentation":"Cassandra validates every partition key supplied to CQL statements in Validation.validateKey. A null key or a key ByteBuffer with zero remaining bytes cannot identify a partition, so an InvalidRequestException is thrown before the statement is executed. This protects the storage engine from writing or reading rows with unusable keys.","triggerScenarios":"Executing INSERT/SELECT/DELETE/UPDATE with a partition key bound to null, an empty string/bytebuffer, or a variable-length key type (text/blob) whose serialized value has 0 remaining bytes.","commonSituations":"Application passes an empty string or unset variable as the primary key; a deserialization bug yields an empty buffer; driver-side null binding of a key column; ETL jobs writing rows with blank key fields.","solutions":["Ensure the application supplies a non-null, non-empty value for every partition key column before executing the statement.","Add application-side validation rejecting rows with empty key fields before sending CQL.","Check bound-variable values in the driver (e.g. a null BoundStatement field) and default or fail early.","If empty keys are legitimately expected, redefine the schema so key components are meaningful (e.g. use a sentinel value or composite key)."],"exampleFix":"// before\nString id = getOptionalId(); // may be \"\"\nsession.execute(\"INSERT INTO users (id, name) VALUES (?, ?)\", id, name);\n// after\nString id = getOptionalId();\nif (id == null || id.isEmpty()) throw new IllegalArgumentException(\"id must be non-empty\");\nsession.execute(\"INSERT INTO users (id, name) VALUES (?, ?)\", id, name);","handlingStrategy":"validation","validationCode":"public static void validatePartitionKey(ByteBuffer key) {\n    if (key == null || key.remaining() == 0)\n        throw new IllegalArgumentException(\"Partition key must be non-null and non-empty\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    session.execute(stmt);\n} catch (InvalidQueryException e) {\n    if (e.getMessage().contains(\"Key may not be empty\")) {\n        log.error(\"Empty partition key supplied; fix key generation\", e);\n    } else throw e;\n}","preventionTips":["Never bind null or empty values to key columns","Validate key fields at the application boundary before CQL is built","Add unit tests covering empty-key rejection","Use non-variable-length key types where possible"],"tags":["cassandra","cql","validation","partition-key"],"backgroundTag":"empty-required-field","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"}