{"record":{"id":"5a9ac0d48fcbe68f","repo":"apache/cassandra","slug":"received-frame-with-custom-payload-flag-for-native","errorCode":null,"errorMessage":"Received frame with CUSTOM_PAYLOAD flag for native protocol version < 4","messagePattern":"Received frame with CUSTOM_PAYLOAD flag for native protocol version < 4","errorType":"exception","errorClass":"org.apache.cassandra.transport.ProtocolException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/transport/Message.java","lineNumber":457,"sourceCode":"            throw ErrorMessage.wrap(e, streamId);\n        }\n    }\n\n    abstract static class Decoder<M extends Message>\n    {\n        static Message decodeMessage(Channel channel, Envelope inbound)\n        {\n            boolean isRequest = inbound.header.type.direction == Direction.REQUEST;\n            boolean isTracing = inbound.header.hasFlag(Flag.TRACING);\n            boolean isCustomPayload = inbound.header.hasFlag(Flag.CUSTOM_PAYLOAD);\n            boolean hasWarning = inbound.header.hasFlag(Flag.WARNING);\n\n            TimeUUID tracingId = isRequest || !isTracing ? null : CBUtil.readTimeUUID(inbound.body);\n            List<String> warnings = isRequest || !hasWarning ? null : CBUtil.readStringList(inbound.body);\n            Map<String, ByteBuffer> customPayload = !isCustomPayload ? null : CBUtil.readBytesMap(inbound.body);\n\n            if (isCustomPayload && inbound.header.version.isSmallerThan(ProtocolVersion.V4))\n                throw new ProtocolException(\"Received frame with CUSTOM_PAYLOAD flag for native protocol version < 4\");\n\n            Message message = inbound.header.type.codec.decode(inbound.body, inbound.header.version);\n            message.setSource(inbound);\n            message.setCustomPayload(customPayload);\n\n            if (isRequest)\n            {\n                assert message instanceof Request;\n                Request req = (Request) message;\n                Connection connection = channel.attr(Connection.attributeKey).get();\n                req.attach(connection);\n                if (isTracing)\n                    req.setTracingRequested();\n            }\n            else\n            {\n                assert message instanceof Response;\n                if (isTracing)","sourceCodeStart":439,"sourceCodeEnd":475,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/transport/Message.java#L439-L475","documentation":"ProtocolException thrown during message decoding when a frame carries the CUSTOM_PAYLOAD flag but the frame's native protocol version is older than V4, which introduced custom payloads. Older protocol versions cannot carry the trailing bytes-map that the flag promises, so the server rejects the frame as malformed. This is a strict version/feature compatibility check.","triggerScenarios":"A client (or driver) claims protocol v3 or lower in the frame header but sets the CUSTOM_PAYLOAD flag (0x04) in the frame's flags byte; decodeMessage in Message.Decoder detects version < V4 together with the flag.","commonSituations":"Driver misconfiguration pinning an old protocol version (e.g. protocolVersion: v3) while using a newer feature such as custom payloads for request tracing tags; mixing driver components of different versions; hand-rolled clients setting flags unconditionally.","solutions":["Raise the client's configured protocol version to V4 or higher (e.g. set protocolVersion to v4/v5 in the driver config).","Update the driver to a modern version that only sets CUSTOM_PAYLOAD on V4+ connections.","If the payload is not needed, remove the custom-payload option from the client configuration.","Audit for mixed-version client libraries that hardcode flags independent of negotiated version."],"exampleFix":"// before: client pinned to old protocol with custom payload enabled\nCluster.builder().addContactPoint(host).withProtocolVersion(ProtocolVersion.V3).build();\n// after: allow V4+ so CUSTOM_PAYLOAD is valid\nCluster.builder().addContactPoint(host).withProtocolVersion(ProtocolVersion.V4).build();","handlingStrategy":"validation","validationCode":"// check version/feature compatibility before enabling custom payloads\nif (chosenProtocolVersion < ProtocolVersion.V4) disableCustomPayload();","typeGuard":null,"tryCatchPattern":"try { connect(); } catch (ProtocolException e) { if (e.getMessage().contains(\"CUSTOM_PAYLOAD\")) { upgradeProtocolVersionOrDisablePayloads(); } }","preventionTips":["Keep drivers current so feature flags match negotiated protocol version","Do not pin old protocol versions while using newer driver features","Enable driver config validation in CI"],"tags":["cassandra","native-protocol","version-compatibility"],"backgroundTag":"invalid-config-value","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"}