{"id":"577320dd44eb6256","repo":"apache/kafka","slug":"malformed-consumer-protocol-assignment","errorCode":null,"errorMessage":"Malformed consumer protocol assignment","messagePattern":"Malformed consumer protocol assignment","errorType":"exception","errorClass":"SchemaException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/clients/consumer/internals/ConsumerProtocol.java","lineNumber":190,"sourceCode":"    public static Assignment deserializeAssignment(final ByteBuffer buffer, short version) {\n        version = checkAssignmentVersion(version);\n\n        try {\n            ConsumerProtocolAssignment data =\n                new ConsumerProtocolAssignment(new ByteBufferAccessor(buffer), version);\n\n            List<TopicPartition> assignedPartitions = new ArrayList<>();\n            for (ConsumerProtocolAssignment.TopicPartition tp : data.assignedPartitions()) {\n                for (Integer partition : tp.partitions()) {\n                    assignedPartitions.add(new TopicPartition(tp.topic(), partition));\n                }\n            }\n\n            return new Assignment(\n                assignedPartitions,\n                data.userData() != null ? data.userData().duplicate() : null);\n        } catch (RuntimeException e) {\n            throw new SchemaException(\"Malformed consumer protocol assignment\", e);\n        }\n    }\n\n    public static Assignment deserializeAssignment(final ByteBuffer buffer) {\n        return deserializeAssignment(buffer, deserializeVersion(buffer));\n    }\n\n    public static ConsumerProtocolAssignment deserializeConsumerProtocolAssignment(\n        final ByteBuffer buffer,\n        short version\n    ) {\n        version = checkAssignmentVersion(version);\n\n        try {\n            return new ConsumerProtocolAssignment(new ByteBufferAccessor(buffer), version);\n        } catch (RuntimeException e) {\n            throw new SchemaException(\"Malformed consumer protocol assignment\", e);\n        }","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/clients/consumer/internals/ConsumerProtocol.java#L172-L208","documentation":"Thrown by ConsumerProtocol.deserializeAssignment(ByteBuffer, short) when reading the assignment payload fails. It wraps the underlying RuntimeException (most often BufferUnderflowException from a truncated payload) in a SchemaException, signalling that the bytes do not conform to the consumer-protocol assignment schema for the supplied version. The leader's assignment, produced by an assignor and forwarded by the broker, is what gets deserialized here.","triggerScenarios":"The consumer receives a SyncGroup response whose assignment ByteBuffer is shorter than expected or whose structure does not match ConsumerProtocolAssignment for the version indicated. Also triggered by custom assignors returning malformed assignment bytes.","commonSituations":"Client/broker version skew after a partial rolling upgrade; custom ConsumerPartitionAssignor that does not use ConsumerProtocol.serializeAssignment; network or compression layer truncating the assignment payload; corrupt group-state replay during coordinator failover.","solutions":["Inspect the wrapped cause via e.getCause() to identify the failing field or the byte shortfall.","Confirm the assignor class is one Kafka ships (RangeAssignor, CooperativeStickyAssignor, etc.) or that the custom assignor delegates serialization to ConsumerProtocol.serializeAssignment.","Roll the consumer group members to the same client version so encoder and decoder agree on the schema.","Force a rejoin (consumer.enforceRebalance() / restart members) to discard any stale assignment payload."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Pre-check buffer sanity before decoding the assignment body.\nstatic void requireReadable(ByteBuffer buffer) {\n    if (buffer == null) throw new IllegalArgumentException(\"buffer == null\");\n    if (buffer.remaining() < Short.BYTES)\n        throw new IllegalArgumentException(\"assignment buffer too short to contain a version header\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    Assignment assignment = ConsumerProtocol.deserializeAssignment(buffer, version);\n} catch (org.apache.kafka.common.protocol.types.SchemaException e) {\n    // Assignment payload (leader->member) is malformed — typically a corrupted/modified\n    // ByteBuffer or a leader running an incompatible consumer protocol version.\n    log.error(\"Malformed consumer protocol assignment\", e);\n    // Re-join the group so a new leader can recompute the assignment.\n}","preventionTips":["Leaders must produce assignments only via ConsumerProtocol.serializeAssignment; hand-rolled byte layout will fail here.","Do not mutate the assignment ByteBuffer between receiving it from the coordinator and deserializing it.","Confirm the assignor class configured on every group member matches; a mismatched assignor produces an assignment this decoder cannot read."],"tags":["consumer","protocol","serialization","schema","assignment"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}