Title: Http errors are not handled properly by streamable_http · Issue #1835 · modelcontextprotocol/python-sdk · GitHub
Open Graph Title: Http errors are not handled properly by streamable_http · Issue #1835 · modelcontextprotocol/python-sdk
X Title: Http errors are not handled properly by streamable_http · Issue #1835 · modelcontextprotocol/python-sdk
Description: Initial Checks I confirm that I'm using the latest version of MCP Python SDK I confirm that I searched for my issue in https://github.com/modelcontextprotocol/python-sdk/issues before opening this issue Description Description When using...
Open Graph Description: Initial Checks I confirm that I'm using the latest version of MCP Python SDK I confirm that I searched for my issue in https://github.com/modelcontextprotocol/python-sdk/issues before opening this ...
X Description: Initial Checks I confirm that I'm using the latest version of MCP Python SDK I confirm that I searched for my issue in https://github.com/modelcontextprotocol/python-sdk/issues before opening t...
Opengraph URL: https://github.com/modelcontextprotocol/python-sdk/issues/1835
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Http errors are not handled properly by streamable_http","articleBody":"### Initial Checks\n\n- [x] I confirm that I'm using the latest version of MCP Python SDK\n- [x] I confirm that I searched for my issue in https://github.com/modelcontextprotocol/python-sdk/issues before opening this issue\n\n### Description\n\n## Description\nWhen using Kiro-CLI with a remote fastMCP server, one issue was observed that when the MCP tool call gets a 403 http error, the cli would hang indefinitely instead of showing an error response.\n\n## Root Cause\nIn `mcp/client/streamable_http.py`, the `_handle_post_request()` method calls `response.raise_for_status()` but doesn't catch the resulting `httpx.HTTPStatusError` exception and convert it to an MCP error response. Without a response message, the client waits indefinitely.\n\n## Expected Behavior\nHTTP errors should be caught and converted to MCP JSON-RPC error responses so clients can handle them gracefully.\n\n## Proposed Fix\nWrap the `response.raise_for_status()` call in a try/except block that catches `httpx.HTTPStatusError` and:\n1. Creates a JSONRPCError with appropriate error details\n2. Sends it to the read stream so the client receives the error\n\nThe temporary patch that fixs the problem:\n~~~\n@wraps(original_handle_post_request)\n async def _handle_post_request_patched(self, ctx: RequestContext) -\u003e None: # type: ignore\n \"\"\"Patched version of _handle_post_request that converts HTTP errors to MCP errors.\n \n This ensures that HTTP errors (like 403 Forbidden) during tool calls are properly\n converted to MCP error messages and sent back to the client, preventing hangs.\n \"\"\"\n try:\n return await original_handle_post_request(self, ctx)\n except httpx.HTTPStatusError as http_error:\n logger.warning('HTTP error in MCP client: %s %s', http_error.response.status_code, http_error.request.url)\n \n # Extract the request ID if this was a request (not a notification)\n message = ctx.session_message.message\n request_id = None\n if isinstance(message.root, mcp.types.JSONRPCRequest):\n request_id = message.root.id\n \n if request_id is not None:\n # Try to parse the error response as an MCP error\n response = http_error.response\n try:\n await response.aread()\n error_body = response.json()\n error_message = error_body.get('message', f'HTTP {response.status_code} error')\n except Exception:\n error_message = f'HTTP {response.status_code} error'\n \n # Create an MCP error response\n jsonrpc_error = mcp.types.JSONRPCError(\n jsonrpc=\"2.0\",\n id=request_id,\n error=mcp.types.ErrorData(\n code=-32603, # Internal error\n message=error_message\n )\n )\n \n # Send the error to the read stream\n session_message = SessionMessage(mcp.types.JSONRPCMessage(jsonrpc_error))\n await ctx.read_stream_writer.send(session_message)\n logger.info('Sent MCP error response for HTTP %s', response.status_code)\n else:\n # For notifications, just log the error\n logger.debug('HTTP error for notification (no response sent): %s', http_error)\n\n StreamableHTTPTransport._handle_post_request = _handle_post_request_patched\n logger.info('Successfully patched MCP client StreamableHTTPTransport._handle_post_request')\n~~~\n\n### Python \u0026 MCP Python SDK\n\n```Text\npython: 3.10.0\nMCP SDK: 1.25.0\n```","author":{"url":"https://github.com/yuxiaorun","@type":"Person","name":"yuxiaorun"},"datePublished":"2026-01-06T18:53:41.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":1},"url":"https://github.com/1835/python-sdk/issues/1835"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:dd84750e-7903-e7a4-b2e5-32d0dc37d49f |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | E818:240318:E570BF:14920F5:6A633018 |
| html-safe-nonce | babc732e43dc1c1cc31dece33119e40c58d507164a342fdfc202e617dfc50fd1 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJFODE4OjI0MDMxODpFNTcwQkY6MTQ5MjBGNTo2QTYzMzAxOCIsInZpc2l0b3JfaWQiOiIxMDMzNzg1MDc1MDE1Mjk5MDk3IiwicmVnaW9uX2VkZ2UiOiJpYWQiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0= |
| visitor-hmac | c5595070206c5de3caab1afe763c73d0b159e134cee3dfe040b77e6c48d9444b |
| hovercard-subject-tag | issue:3786173755 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/modelcontextprotocol/python-sdk/1835/issue_layout |
| twitter:image | https://opengraph.githubassets.com/68962fc9c5acbd874705180ce0b7adcf3ab0d1bc7e98007f5254fd872fb4cc55/modelcontextprotocol/python-sdk/issues/1835 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/68962fc9c5acbd874705180ce0b7adcf3ab0d1bc7e98007f5254fd872fb4cc55/modelcontextprotocol/python-sdk/issues/1835 |
| og:image:alt | Initial Checks I confirm that I'm using the latest version of MCP Python SDK I confirm that I searched for my issue in https://github.com/modelcontextprotocol/python-sdk/issues before opening this ... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | yuxiaorun |
| hostname | github.com |
| expected-hostname | github.com |
| None | df6e1c2adcceb061ec8c4106a1b34f38280f08e13f2b195c661c202834cbc3b1 |
| turbo-cache-control | no-preview |
| go-import | github.com/modelcontextprotocol/python-sdk git https://github.com/modelcontextprotocol/python-sdk.git |
| octolytics-dimension-user_id | 182288589 |
| octolytics-dimension-user_login | modelcontextprotocol |
| octolytics-dimension-repository_id | 862584018 |
| octolytics-dimension-repository_nwo | modelcontextprotocol/python-sdk |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 862584018 |
| octolytics-dimension-repository_network_root_nwo | modelcontextprotocol/python-sdk |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 822a0ff2a479845adcdd40a1a7b1734a56e05818 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width