Skip to content

Client never answers a server ping sent during the initialize handshake #1362

Closed

Description

@gocamille

Describe the bug

This is about the 2025-11-25 initialize handshake. While the client waits for the initialize response, expect_response in service/client.rs drops any ping from the server:

// Server could send pings before handshake
ServerJsonRpcMessage::Request(ref request)
    if matches!(request.request, ServerRequest::PingRequest(_)) =>
{
    tracing::trace!("Received ping request. Ignored.")
}

Nothing is written back, so the server's ping never gets a response. A server that times out its pings can treat the connection as stale and drop it. A ping sent after notifications/initialized is answered normally.

The server side already does this. #745 made the server answer a client ping that arrives before initialize.

To Reproduce (main at 8d226f4)

Over a tokio::io::duplex transport, with both sides on 2025-11-25, a raw server reads initialize, writes a ping, and then writes the InitializeResult:

<- {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"capabilities":{},"clientInfo":{"name":"rmcp","version":"3.5.1"},"protocolVersion":"2025-11-25"}}
-> {"jsonrpc":"2.0","id":"srv-ping-pre","method":"ping"}
-> {"jsonrpc":"2.0","id":0,"result":{"protocolVersion":"2025-11-25","capabilities":{},"serverInfo":{...}}}

After notifications/initialized arrives, it sends a second ping (srv-ping-post) for comparison. Everything the client writes back:

{"jsonrpc":"2.0","method":"notifications/initialized"}
{"jsonrpc":"2.0","id":"srv-ping-post","result":{}}

There is no response for srv-ping-pre.

Expected behavior

The client writes {"jsonrpc":"2.0","id":"srv-ping-pre","result":{}} during the handshake and then carries on waiting for the InitializeResult.

Additional context

The 2025-11-25 lifecycle lets the server send pings before it gets notifications/initialized, and the ping page says the receiver MUST respond promptly with an empty response.

expect_response is also used while waiting for server/discover. 2026-07-28 removes ping and servers there don't send requests, so I'd leave that path as it is and only answer during initialize.

I can open a PR for this.

Activity

  1. added
    bugSomething is not working
    P1High: significant functionality gap or spec violation
    T-serviceService layer changes
    ready for workIssue is well-defined and ready to be picked up
    on Oct 14, 2026
  2. github-actions commented on Oct 14, 2026

    @github-actions
    Contributor

    @bolinfest is on triage rotation this week and is the reviewer for this one.

    Codex labeled this bug / P1 (T-service). Please confirm or correct those labels.

    Automated triage. Labels are a first pass and the assigned maintainer has the final say.

  3. gocamille commented on Oct 14, 2026

    @gocamille
    ContributorAuthor

    I have a fix with tests on my fork: https://github.com/gocamille/rust-sdk/tree/fix/client-ping-during-initialize. I'm at the open-PR limit with #1361, so I'll open the PR once that one lands.

  4. gocamille commented on Oct 15, 2026

    @gocamille
    ContributorAuthor

    Opened the fix as a draft in #1366, since the open-PR limit still applies with #1361 open. Happy to mark it ready once that one lands, or sooner if a maintainer wants to.

  5. added a commit that references this issue on Oct 16, 2026
    9412d6c
  6. added a commit that references this issue on Oct 16, 2026
    a156be8
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

P1High: significant functionality gap or spec violationT-serviceService layer changesbugSomething is not workingready for workIssue is well-defined and ready to be picked up

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions