Repository navigation
FastMCP read_resource() returns incorrect error code when resource not found #1579
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
It appears to be unclear as to how an MCP server should respond to a read resource request if the resource is not found, however, FastMCP returns error code 0, which seems likely incorrect regardless.
In the Error Handling part of the protocol specification it states:
Resource not found:
-32002
However, the python SDK's FastMCP attempts to raise a ResourceError, except it appears that code would never get executed because a ValueError is raised in ResourceManager first.
The net result of this is that servers implemented using FastMCP return the following for resource-not-found:
{"jsonrpc":"2.0","id":7,"error":{"code":0,"message":"Unknown resource: https://example.com/does-not-exist"}}For the purposes of comparison, I compared this to the (presumably reference) typescript implementation, which raises an MCP error with InvalidParams: code -32602 - see here
-32602 is notably similar to -32002, but also seemingly incorrect (though in a different way ☹).
As things stand today, it is rather difficult to reliably write clients that behave predictably due to this. I understand this may be more of a protocol specification problem than a python-sdk problem, but error code 0 seems incorrect either way, so thought I'd report it.
Example Code
Basic server (anything will do):
from mcp.server.fastmcp import FastMCP
mcp = FastMCP('Pydantic AI MCP Server')
log_level = 'unset'
@mcp.resource('resource://user_name.txt', mime_type='text/plain')
async def user_name_resource() -> str:
return 'Alice'
if __name__ == '__main__':
mcp.run(transport='streamable-http')Then try to fetch any resource via whatever MCP client you like, eg (manual curl):
MCP_URL="http://localhost:8000/mcp"
SESSION_ID=""
# Step 1: Initialize and get session ID
echo "1. Initializing MCP server..."
INIT_RESPONSE=$(curl -s -D - -X POST "$MCP_URL" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": {
"name": "test-mcp-script",
"version": "1.0.0"
}
},
"id": 1
}')
# Extract session ID from headers
SESSION_ID=$(echo "$INIT_RESPONSE" | grep -i 'mcp-session-id:' | cut -d' ' -f2 | tr -d '\r')
# Try to read resource:
curl -s -X POST "$MCP_URL" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Mcp-Session-Id: $SESSION_ID" \
-d '{
"jsonrpc": "2.0",
"method": "resources/read",
"params": {
"uri": "https://example.com/does-not-exist"
},
"id": 7
}'
# > event: message
# > data: {"jsonrpc":"2.0","id":7,"error":{"code":0,"message":"Unknown resource: https://example.com/does-not-exist"}}Python & MCP Python SDK
`main`
Activity
maxisbey commentedon Nov 5, 2025
Thank you for the report! It would be great if you could provide some example code for the server/client with which shows the errors and what you'd expect, or hope to be consistent.
fennb commentedon Nov 5, 2025
Done!
fennb commentedon Nov 6, 2025
Wait, before we go further on this, I just found this: modelcontextprotocol/modelcontextprotocol#1545
It looks like the spec itself is wrong☹️ . I haven't read the whole thread but this may change the answer as to what the right solution is.
tpamsler commentedon Nov 16, 2025
I am getting the same error after updating FastMCP from v2.12.5 to v2.13.0.2. The error originates in mcp/shared/session.py → BaseSession → send_reques()
Here is our resource template declaration:
fix: return INVALID_PARAMS (-32602) error code for resource-not-found
maxisbey commentedon Jul 29, 2026
Thanks for the report. Closing this as it's been fixed in v2, which is now released (see #2920). Feel free to reopen if you still hit it on v2.
AI Disclaimer