Skip to content

mcp-kafka: reset_offsets hangs forever when target consumer group state is Dead #2532

Description

@jfallows

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

  1. Ensure a consumer group has never existed / has no committed state (e.g. orders-analytics, confirmed via kafka-consumer-groups.sh --describe --group orders-analyticsGroupIdNotFoundException; 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).

  2. Call kafka__reset_offsets with group_id=orders-analytics, topic=orders, partition=0, offset=0.

  3. 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_COORDINATORSTAGE_DESCRIBE_GROUPSSTAGE_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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions