Skip to content

FastMCP server death on client HEAD calls #1269

Open

Description

@chipkent

Initial Checks

Description

I am using streamable HTTP for MCP. I see HTTP HEAD calls in the log which killing the server. I expect the server to be resilient to poor user behavior.

My code:
https://github.com/deephaven/deephaven-mcp/tree/main/src/deephaven_mcp/mcp_docs_server

Example logs:

2025-08-13 09:29:26.178 PDT
[2025-08-13 16:29:26,179] INFO: [mcp_docs_server:app_lifespan] MCP docs server ready and yielding context
2025-08-13 09:29:26.179 PDT
INFO: 169.254.169.126:65146 - "HEAD /mcp HTTP/1.1" 405 Method Not Allowed
2025-08-13 09:29:26.179 PDT
[2025-08-13 16:29:26,180] INFO: Terminating session: None
2025-08-13 09:29:26.183 PDT
[2025-08-13 16:29:26,180] ERROR: Error in message router
2025-08-13 09:29:26.183 PDT
Traceback (most recent call last):
  File "/app/.venv/lib/python3.12/site-packages/mcp/server/streamable_http.py", line 831, in message_router
    async for session_message in write_stream_reader:
  File "/app/.venv/lib/python3.12/site-packages/anyio/abc/_streams.py", line 41, in __anext__
    return await self.receive()

2025-08-13 09:29:26.183 PDT
^^^^^^^^^^^^^^^^^^^^
2025-08-13 09:29:26.183 PDT
File "/app/.venv/lib/python3.12/site-packages/anyio/streams/memory.py", line 111, in receive
2025-08-13 09:29:26.183 PDT
return self.receive_nowait()
2025-08-13 09:29:26.183 PDT
^^^^^^^^^^^^^^^^^^^^^
2025-08-13 09:29:26.183 PDT
File "/app/.venv/lib/python3.12/site-packages/anyio/streams/memory.py", line 93, in receive_nowait
2025-08-13 09:29:26.183 PDT
raise ClosedResourceError
2025-08-13 09:29:26.183 PDT
anyio.ClosedResourceError
2025-08-13 09:29:26.183 PDT
[2025-08-13 16:29:26,184] INFO: [mcp_docs_server:app_lifespan] Context manager exiting normally
2025-08-13 09:29:26.184 PDT
[2025-08-13 16:29:26,184] INFO: [mcp_docs_server:app_lifespan] Final memory usage: 109.02 MB
2025-08-13 09:29:26.184 PDT
[2025-08-13 16:29:26,184] INFO: [mcp_docs_server:app_lifespan] Final CPU percent: 0.0%
2025-08-13 09:29:26.184 PDT
[2025-08-13 16:29:26,184] INFO: [mcp_docs_server:app_lifespan] Final open file descriptors: 11
2025-08-13 09:29:26.184 PDT
[2025-08-13 16:29:26,185] INFO: [mcp_docs_server:app_lifespan] shutdown active asyncio tasks: 3
2025-08-13 09:29:26.184 PDT
[2025-08-13 16:29:26,185] WARNING: [mcp_docs_server:app_lifespan] Running tasks during shutdown: 3
2025-08-13 09:29:26.184 PDT
[2025-08-13 16:29:26,185] WARNING: [mcp_docs_server:app_lifespan] Running task 1: mcp.server.streamable_http_manager.StreamableHTTPSessionManager._handle_stateless_request.<locals>.run_stateless_server
2025-08-13 09:29:26.184 PDT
[2025-08-13 16:29:26,185] WARNING: [mcp_docs_server:app_lifespan] Running task 2: Task-2
2025-08-13 09:29:26.184 PDT
[2025-08-13 16:29:26,185] WARNING: [mcp_docs_server:app_lifespan] Running task 3: mcp.server.fastmcp.server.FastMCP.run_streamable_http_async
2025-08-13 09:29:26.184 PDT
[2025-08-13 16:29:26,185] INFO: [mcp_docs_server:app_lifespan] shutdown active threads: 1
2025-08-13 09:29:26.185 PDT
[2025-08-13 16:29:26,185] INFO: [mcp_docs_server:app_lifespan] MCP docs server shutting down

My attempts to work around this problem are in this PR. You would need to look at the whole history of what I tried. I included different middleware changes, increasing versions, etc.
deephaven/deephaven-mcp#89

Example Code

My code:
https://github.com/deephaven/deephaven-mcp/tree/main/src/deephaven_mcp/mcp_docs_server

Python & MCP Python SDK

The build can be found at https://github.com/deephaven/deephaven-mcp/blob/main/ops/docker/mcp-docs/Dockerfile.  It is python 3.12 with the latest mcp (version >= 1.12.4).

Activity

  1. added
    needs confirmationNeeds confirmation that the PR is actually required or needed.
    on Aug 13, 2025
  2. chipkent commented on Aug 13, 2025

    @chipkent
    Author

    The ticket for my project that may have more details is: deephaven/deephaven-mcp#90

  3. jzwick-narmi commented on Sep 15, 2025

    @jzwick-narmi

    I am also having this issue

    Image
  4. added
    needs reproneeds additional information to be able to reproduce bug
    and removed
    needs confirmationNeeds confirmation that the PR is actually required or needed.
    on Oct 3, 2025
  5. felixweinberger commented on Oct 3, 2025

    @felixweinberger
    Contributor

    Hi @chipkent thanks for reporting this; would you be able to provide a snippet we could run to isolate the issue you're seeing here? I see you linked to your repo, but it'd be great if you could isolate the repro to the specific issue here if possible.

  6. DinoChiesa commented on Oct 21, 2025

    @DinoChiesa

    I observed something related...
    HEAD gets a 405 from my FastMCP server, but the server does not "exit" when handling this.

    On the other hand, when a faulty client sent a POST with no payload, this caused a parse error in the server, which lead to the same stack trace shown here, and server exit. Correcting my client to send a valid JSONRPC payload allowed the server to stay up.

    I agree the server should be able to remain running in the face of ill-behaved clients.

  7. added
    P2Moderate issues affecting some users, edge cases, potentially valuable feature
    ready for workEnough information for someone to start working on
    and removed
    needs reproneeds additional information to be able to reproduce bug
    on Oct 21, 2025
  8. added a commit that references this issue on Mar 1, 2026
    82d4d14
  9. Br1an67 commented on Mar 1, 2026

    @Br1an67

    I'd like to work on this. The fix rejects unsupported HTTP methods (HEAD, PUT, etc.) early in StreamableHTTPSessionManager.handle_request() before any transport or background task is created, preventing the ClosedResourceError race condition.

    PR: #2191

  10. DinoChiesa commented on Mar 1, 2026

    @DinoChiesa

    This report and this report both said that the client sees 405 and no server exit when sending the unsupported HEAD method.

    What does your fix change?

    The latter report states

    when a faulty client sent a POST with no payload, this caused a parse error in the server, which lead to the same stack trace shown here, and server exit.

    Does your fix address this problem? rejecting HEAD or PUT before any transport task seems irrelevant to that problem.

    What does your fix change?

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

    P2Moderate issues affecting some users, edge cases, potentially valuable featurebugSomething isn't workingready for workEnough information for someone to start working on

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions