Found while smoke-testing the Kafka MCP toolkit against develop-SNAPSHOT, confirmed via zilla dump.
Symptom
kafka__reset_offsets against a consumer group that has never had any members (broker reports it as Dead, e.g. one that was never created by an active consumer) hangs indefinitely — no response, no error, no progress — until the MCP client's own idle timeout eventually gives up (300s in our case).
Repro
-
Ensure a consumer group has never existed / has no committed state (e.g. orders-analytics, confirmed via kafka-consumer-groups.sh --describe --group orders-analytics → GroupIdNotFoundException; the MCP describe_consumer_group tool reports it as {"group_id":"orders-analytics","state":"Dead","members":[]}, which is the normal/expected shape for a nonexistent group).
-
Call kafka__reset_offsets with group_id=orders-analytics, topic=orders, partition=0, offset=0.
-
The call never returns. Repeated with a fresh zilla dump capture on example.south_mcp_kafka_client0 running throughout: the wire trace shows exactly two successful Kafka round trips —
FindCoordinator (v3) → Error: No Error (0), coordinator = node 1
DescribeGroups (v5) → Error: No Error (0), group state Dead
— and then nothing. No third Kafka request is ever sent, and no HTTP response is ever sent back to the MCP client, for the remainder of the capture window.
Implicated code
runtime/binding-mcp-kafka/.../stream/McpKafkaProxyFactory.java, KafkaApiResetOffsetsClient (~line 8730 onward). This is a 3-stage flow: STAGE_FIND_COORDINATOR → STAGE_DESCRIBE_GROUPS → STAGE_OFFSET_COMMIT. RESETTABLE_GROUP_STATES (line 257) explicitly includes both "Empty" and "Dead", and completeDescribeGroups (line 8960) correctly takes the "proceed" branch for a Dead group, calling advanceToOffsetCommit(traceId) (line 8993), which ends the DescribeGroups stream and opens a new Kafka stream carrying an offsetCommit begin-extension (built with groupId/memberId("")/instanceId("")/coordinatorHost/coordinatorPort, line 9029-9037) — the actual bare-commit request payload is only sent later, from sendOffsetCommit, once a WINDOW arrives for that new stream (onKafkaWindow, line 9069-9097, default case).
Per the pcap, that new stream's BEGIN is either never actually dispatched south, or never receives a WINDOW back — either way, sendOffsetCommit is never reached, so the flow stalls forever in STAGE_OFFSET_COMMIT with no request sent and no error surfaced to the MCP client.
Impact
Any reset_offsets call against an inactive/nonexistent consumer group — which per the code's own RESETTABLE_GROUP_STATES comment is meant to be the normal, supported case (mirroring AdminClient.alterConsumerGroupOffsets() against an inactive group) — hangs the calling client indefinitely instead of completing or failing fast.
Suggested fix
Investigate why the third (STAGE_OFFSET_COMMIT) stream's BEGIN/WINDOW handshake never completes when advancing from DescribeGroups, and add a bounded timeout so this flow fails fast with a clear error instead of hanging forever.
Found while smoke-testing the Kafka MCP toolkit against
develop-SNAPSHOT, confirmed viazilla dump.Symptom
kafka__reset_offsetsagainst a consumer group that has never had any members (broker reports it asDead, e.g. one that was never created by an active consumer) hangs indefinitely — no response, no error, no progress — until the MCP client's own idle timeout eventually gives up (300s in our case).Repro
Ensure a consumer group has never existed / has no committed state (e.g.
orders-analytics, confirmed viakafka-consumer-groups.sh --describe --group orders-analytics→GroupIdNotFoundException; the MCPdescribe_consumer_grouptool reports it as{"group_id":"orders-analytics","state":"Dead","members":[]}, which is the normal/expected shape for a nonexistent group).Call
kafka__reset_offsetswithgroup_id=orders-analytics,topic=orders,partition=0,offset=0.The call never returns. Repeated with a fresh
zilla dumpcapture onexample.south_mcp_kafka_client0running throughout: the wire trace shows exactly two successful Kafka round trips —FindCoordinator(v3) →Error: No Error (0), coordinator = node 1DescribeGroups(v5) →Error: No Error (0), group stateDead— and then nothing. No third Kafka request is ever sent, and no HTTP response is ever sent back to the MCP client, for the remainder of the capture window.
Implicated code
runtime/binding-mcp-kafka/.../stream/McpKafkaProxyFactory.java,KafkaApiResetOffsetsClient(~line 8730 onward). This is a 3-stage flow:STAGE_FIND_COORDINATOR→STAGE_DESCRIBE_GROUPS→STAGE_OFFSET_COMMIT.RESETTABLE_GROUP_STATES(line 257) explicitly includes both"Empty"and"Dead", andcompleteDescribeGroups(line 8960) correctly takes the "proceed" branch for aDeadgroup, callingadvanceToOffsetCommit(traceId)(line 8993), which ends theDescribeGroupsstream and opens a new Kafka stream carrying anoffsetCommitbegin-extension (built withgroupId/memberId("")/instanceId("")/coordinatorHost/coordinatorPort, line 9029-9037) — the actual bare-commit request payload is only sent later, fromsendOffsetCommit, once aWINDOWarrives for that new stream (onKafkaWindow, line 9069-9097,defaultcase).Per the pcap, that new stream's
BEGINis either never actually dispatched south, or never receives aWINDOWback — either way,sendOffsetCommitis never reached, so the flow stalls forever inSTAGE_OFFSET_COMMITwith no request sent and no error surfaced to the MCP client.Impact
Any
reset_offsetscall against an inactive/nonexistent consumer group — which per the code's ownRESETTABLE_GROUP_STATEScomment is meant to be the normal, supported case (mirroringAdminClient.alterConsumerGroupOffsets()against an inactive group) — hangs the calling client indefinitely instead of completing or failing fast.Suggested fix
Investigate why the third (
STAGE_OFFSET_COMMIT) stream'sBEGIN/WINDOWhandshake never completes when advancing fromDescribeGroups, and add a bounded timeout so this flow fails fast with a clear error instead of hanging forever.