{"record":{"id":"d4335d9637787b17","repo":"apache/cassandra","slug":"invalid-query-kind-in-batch-messages-must-be-0-or","errorCode":null,"errorMessage":"Invalid query kind in BATCH messages. Must be 0 or 1 but got ","messagePattern":"Invalid query kind in BATCH messages\\. Must be 0 or 1 but got ","errorType":"exception","errorClass":"ProtocolException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/transport/messages/BatchMessage.java","lineNumber":70,"sourceCode":"public class BatchMessage extends Message.Request\n{\n    public static final Message.Codec<BatchMessage> codec = new Message.Codec<BatchMessage>()\n    {\n        public BatchMessage decode(ByteBuf body, ProtocolVersion version)\n        {\n            byte type = body.readByte();\n            int n = body.readUnsignedShort();\n            List<Object> queryOrIds = new ArrayList<>(n);\n            List<byte[][]> variables = new ArrayList<>(n);\n            for (int i = 0; i < n; i++)\n            {\n                byte kind = body.readByte();\n                if (kind == 0)\n                    queryOrIds.add(CBUtil.readLongString(body));\n                else if (kind == 1)\n                    queryOrIds.add(MD5Digest.wrap(CBUtil.readBytes(body)));\n                else\n                    throw new ProtocolException(\"Invalid query kind in BATCH messages. Must be 0 or 1 but got \" + kind);\n                variables.add(CBUtil.readValueListAsByteArrays(body, version));\n            }\n            QueryOptions options = QueryOptions.codec.decode(body, version);\n\n            return new BatchMessage(toType(type), queryOrIds, variables, options);\n        }\n\n        public void encode(BatchMessage msg, ByteBuf dest, ProtocolVersion version)\n        {\n            int queries = msg.queryOrIdList.size();\n\n            dest.writeByte(fromType(msg.batchType));\n            dest.writeShort(queries);\n\n            for (int i = 0; i < queries; i++)\n            {\n                Object q = msg.queryOrIdList.get(i);\n                dest.writeByte((byte)(q instanceof String ? 0 : 1));","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/transport/messages/BatchMessage.java#L52-L88","documentation":"ProtocolException from BatchMessage.codec.decode when the per-query kind byte in a CQL BATCH frame is neither 0 (query string) nor 1 (prepared id). The client sent a malformed batch frame, so decoding fails and the connection is typically closed.","triggerScenarios":"A malformed or corrupted BATCH frame whose per-statement kind byte is not 0 or 1 — typically a hand-rolled client, buggy proxy rewriting frames, or desynchronization from a bad length prefix earlier in the body.","commonSituations":"Custom native-protocol client implementations encoding the kind byte incorrectly; frame corruption from mismatched compression settings; fuzzing or version-mismatched middleware.","solutions":["Fix the producer to write kind=0 for query strings and kind=1 for prepared IDs.","Verify compression and framing configuration match between client and server (corruption shifts byte boundaries).","Capture and hexdump the offending BATCH frame to confirm byte layout against the protocol spec.","Use the official java driver's batch API instead of hand-encoding frames."],"exampleFix":"// before\nbody.writeByte(2); // invalid kind\n// after\nbody.writeByte(0); // 0 = query string, 1 = prepared statement id","handlingStrategy":"validation","validationCode":"// when hand-encoding a batch entry\nint kind = stmt instanceof String ? 0 : 1;\nif (kind != 0 && kind != 1) throw new IllegalArgumentException(\"kind must be 0 or 1\");","typeGuard":null,"tryCatchPattern":"try { batch(); } catch (ProtocolException e) { if (e.getMessage().contains(\"Invalid query kind\")) dumpAndInspectFrame(); }","preventionTips":["Encode kind=0 for query strings, kind=1 for prepared IDs","Prefer the java driver over hand-rolled frames","Match compression settings to avoid byte-shift corruption"],"tags":["batch","protocol","deserialization","native-protocol"],"backgroundTag":"invalid-enum-value","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}