{"record":{"id":"f6272727e8d5045b","repo":"apache/cassandra","slug":"unknown-option-id-d","errorCode":null,"errorMessage":"Unknown option id %d","messagePattern":"Unknown option id (.+?)","errorType":"exception","errorClass":"org.apache.cassandra.transport.ProtocolException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/transport/DataType.java","lineNumber":365,"sourceCode":"                if (existingType != null)\n                    throw new IllegalStateException(String.format(\"Duplicate option id %d\", id));\n                ids[id] = opt;\n            }\n        }\n\n        private int getMaxId(DataType[] values)\n        {\n            int maxId = -1;\n            for (DataType opt : values)\n                maxId = Math.max(maxId, opt.getId(ProtocolVersion.CURRENT));\n            return maxId;\n        }\n\n        private DataType fromId(int id)\n        {\n            DataType opt = ids[id];\n            if (opt == null)\n                throw new ProtocolException(String.format(\"Unknown option id %d\", id));\n            return opt;\n        }\n\n        public Pair<DataType, Object> decodeOne(ByteBuf body, ProtocolVersion version)\n        {\n            DataType opt = fromId(body.readUnsignedShort());\n            Object value = opt.readValue(body, version);\n            return Pair.create(opt, value);\n        }\n\n        public void writeOne(Pair<DataType, Object> option, ByteBuf dest, ProtocolVersion version)\n        {\n            DataType opt = option.left;\n            Object obj = option.right;\n            dest.writeShort(opt.getId(version));\n            opt.writeValue(obj, dest, version);\n        }\n","sourceCodeStart":347,"sourceCodeEnd":383,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/transport/DataType.java#L347-L383","documentation":"Each data type in the native protocol has a numeric option id. DataType.fromId looks up the id in the ids table and throws this ProtocolException when no DataType is registered for it, i.e. the client sent an unrecognized type code in metadata.","triggerScenarios":"A frame's type-spec section contains an unsigned short option id that does not map to any known DataType (corrupt frame, newer protocol type codes sent to an older server, or fuzzed input).","commonSituations":"Newer driver speaking type codes the older server doesn't know; corrupted metadata; proxies rewriting frames.","solutions":["Align client driver version with server version so type codes match.","Force a mutually supported protocol version on the client.","Capture and inspect the frame's option id to confirm which code is being sent.","Regenerate/refresh prepared statement metadata if it was cached from a different server version."],"exampleFix":"// before: hardcoded newer protocol\ncluster.setProtocolVersion(ProtocolVersion.V5); // server only supports V4\n// after\ncluster.setProtocolVersion(ProtocolVersion.V4); // or let driver negotiate","handlingStrategy":"validation","validationCode":"// confirm the type code exists before sending metadata\nshort id = ...;\nif (id >= KNOWN_TYPE_IDS.length || KNOWN_TYPE_IDS[id] == null)\n    fail(\"Unknown data type id: \" + id);","typeGuard":"null","tryCatchPattern":"try { session.execute(...); } catch (ProtocolException e) {\n    if (e.getMessage().startsWith(\"Unknown option id\")) {\n        // switch protocol version or upgrade driver/server\n    }\n}","preventionTips":["Use a driver version that matches the server's protocol version.","Avoid sending hand-built type metadata; rely on driver metadata codecs.","Clear cached prepared-statement metadata after version changes.","Test against the oldest server version you must support."],"tags":["protocol","types","invalid-enum","cql-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"}