Skip to content

vMCP health check re-sends "initialize" to stdio backends, which reject it (duplicate "initialize" received) and get marked unhealthy #5890

Description

@Tanguille

Running vmcp v0.40.1 (Kubernetes operator). I have a couple of stdio MCP backends aggregated into vMCPs — GitHub's github-mcp-server:v1.6.0 with transport: stdio, one instance in the resources group and one in the all group (my unified gateway).

The vMCP health monitor keeps marking these stdio backends unhealthy with:

health check failed: backend unavailable: failed to initialize client for backend github-opt:
  calling "initialize": duplicate "initialize" received

The health check appears to open a client and send initialize, but a stdio backend is a single long-lived subprocess with one session — once it's been initialized, a second initialize is rejected as duplicate "initialize" received. Every health cycle then fails the same way, the backend crosses the failure threshold, and the vMCPs that aggregate it (for me resources and unified) get degraded. That drags down the other tools on those gateways too, not just GitHub.

I ended up removing the GitHub backends entirely to stop them degrading the rest of the gateway, so I don't have it live to capture a fresh trace — but the error is deterministic and reproduces with any stdio backend behind a vMCP.

Would it make sense for the health check to not re-initialize an already-initialized stdio session — e.g. use a lightweight ping, or reuse the existing session/health state rather than standing up a fresh initialize each cycle? HTTP/SSE backends get a fresh connection per check so they're unaffected; it's specifically stdio (one process, one session) that breaks.

Versions: vmcp v0.40.1, github-mcp-server v1.6.0, transport stdio.

Activity

  1. added
    bugSomething isn't working
    vmcpVirtual MCP Server related issues
    and removed
    needs-triageIssue needs initial triage by a maintainer
    on Jul 30, 2026
  2. ChrisJBurns commented on Jul 30, 2026

    @ChrisJBurns
    Collaborator

    Thanks for the report, @Tanguille, and sorry for the slow reply. Your diagnosis was right: the health check stands up a fresh client and handshakes each cycle, and a stdio backend is one process with one session, so the second initialize is rejected.

    A fix is already in flight in #6153, which serves a repeat initialize from a cached result rather than forwarding it to the single stdio session.

    One thing worth knowing, because it affects your workaround. The problem is wider than the health check: every vMCP call verb builds a fresh client and handshakes, so once the aggregator has claimed the single handshake at startup, tool calls against a stdio backend fail for the same reason. The lightweight ping you suggested would have quietened the health check while leaving that broken, so #6153 fixes it at the handshake instead.

    Keeping this open until #6153 lands, at which point it will close automatically.

  3. amirejaz commented on Aug 14, 2026

    @amirejaz
    Contributor

    Following up on Chris's note above: this landed, and it took three changes rather than just #6153 — #6153 (serve a repeat initialize from a cached result), #6158 (a revision-classification oscillation that degraded the same backend from a different angle), and #6184 (a removed logging/setLevel RPC that was killing tool calls while health checks stayed green).

    All three are in v0.42.1. Worth upgrading straight to that rather than v0.41.0 — v0.41.0 has the latter two unfixed, so the gateway would still degrade, just for different reasons.

    Verified against your setup before closing: vMCP with github-mcp-server v1.6.0 over stdio, 20/20 health checks passing, gateway staying Ready, and tool calls returning real data.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingvmcpVirtual MCP Server related issues

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions