MCP Error Codes
If you've worked with APIs before, you know that error codes can feel like cryptic messages from another dimension. The Model Context Protocol (MCP) uses a well-structured error code system that, once understood, makes debugging significantly easier. Let's explore these error codes and what they tell you about your MCP integrations.
Error Code Structure in MCP
MCP builds on JSON-RPC 2.0 for its error representation. When something goes wrong, you receive an error object structured like this:
{
jsonrpc: "2.0",
id: string | number | null,
error: {
code: number,
message: string,
data?: unknown
}
}
The code
field contains the numeric identifier that categorizes the error type. Think of it as the error's fingerprint, and a specific number means a specific problem. The message
field gives you a human-readable explanation, while the data
field offers additional context to help diagnose and fix the issue.
Standard JSON-RPC Error Codes
MCP inherits several standard error codes from JSON-RPC 2.0, using the reserved range from -32768
to -32000
:
Code | Name | What it Really Means |
---|---|---|
-32700 |
Parse Error | Your JSON syntax is broken |
-32600 |
Invalid Request | Your message structure violates the protocol |
-32601 |
Method Not Found | The operation you requested doesn't exist |
-32602 |
Invalid Params | Your parameters failed validation |
-32603 |
Internal Error | The server encountered an implementation issue |
-32000 to -32099 |
Server Error | Implementation-specific errors |
Parse Error (-32700
)
A parse error occurs when the JSON syntax in your message is invalid. The server can't even begin to process your request because the message structure is broken. You might have an unterminated string, unbalanced brackets, or invalid Unicode sequences.
The server response looks like:
{
"jsonrpc": "2.0",
"error": {"code": -32700, "message": "Parse error"},
"id": null
}
The id
field is null because the server couldn't determine which request is yours from the broken JSON. During development, these errors often appear when manually crafting requests or when your JSON serialization has issues.
Invalid Request (-32600
)
An invalid request indicates that your JSON was syntactically valid, but the structure violates the protocol requirements. Perhaps you omitted the required jsonrpc
field or used the wrong data type for one of the standard fields.
The response might look like:
{
"jsonrpc": "2.0",
"error": {"code": -32600, "message": "Invalid Request: missing method field"},
"id": null
}
The protocol validates structural integrity before processing content, so these errors happen early in the request lifecycle.
Method Not Found (-32601
)
This error appears when you attempt to call a method the server doesn't support. You might be trying to use features from a different MCP version, or the server might not implement optional capabilities you expect.
The server responds with:
{
"jsonrpc": "2.0",
"error": {"code": -32601, "message": "Method 'tools/update' not found"},
"id": "abc123"
}
These errors often stem from capability mismatches or method name typos. The error includes your original request ID so you can correlate it with the failed request.
Invalid Parameters (-32602
)
Parameter validation failures produce invalid parameter errors. Your method exists, but the arguments you provided don't meet the requirements. Maybe you passed a number where a string was expected, or omitted a required field:
{
"jsonrpc": "2.0",
"error": {
"code": -32602,
"message": "Invalid params: uri must be a string",
"data": {"path": "uri", "expected": "string", "received": "number"}
},
"id": 42
}
The error's data
field often contains validation details to help you correct your request. This is the most common error during active development as you refine your tool arguments and resource references.
Internal Error (-32603
)
An internal error indicates that something went wrong inside the server. Your request was valid, but the server encountered problems during execution. For example:
{
"jsonrpc": "2.0",
"error": {"code": -32603, "message": "Internal error: database connection failed"},
"id": "xyz789"
}
These errors can be particularly frustrating because they stem from issues beyond your control. For example, server dependencies might be down, reached some resource limits, or triggered certain implementation bugs.
Server Errors (-32000
to -32099
)
The range from -32000
to -32099
allows for implementation-specific errors:
{
"jsonrpc": "2.0",
"error": {
"code": -32050,
"message": "Rate limit exceeded",
"data": {"retryAfter": 60}
},
"id": "abc123"
}
Server implementers choose these codes to provide clearer information about what went wrong. You'll commonly see -32002
for "Resource not found" and various other codes for authentication, rate limiting, and server-specific conditions.
Custom Application Error Codes
While MCP defines several standard error codes in the reserved range (-32768
to -32000
), implementers can also define their own custom error codes outside this range for application-specific errors.
According to the JSON-RPC 2.0 specification that MCP builds upon, any error code outside the reserved range can be used for custom application-defined errors. While there's no official handbook for these custom codes, many implementations follow a convention of organizing codes by category (e.g., -31xxx
for authentication, -30xxx
for resource access).
When implementing your own MCP server, you can define error codes like this:
// Example of custom error codes for an MCP server
const ErrorCodes = {
// Authentication errors (-31xxx range)
AUTH_REQUIRED: -31001,
INVALID_TOKEN: -31002,
// Resource access errors (-30xxx range)
RESOURCE_LOCKED: -30001,
QUOTA_EXCEEDED: -30002
};
MCP-Specific Error Patterns
Beyond standard error codes, MCP defines specialized error patterns for its core features. Understanding these patterns helps you handle errors more intelligently.
Initialization Errors
When first connecting to an MCP server, you exchange protocol versions and capabilities. Version incompatibilities generate specific errors:
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32602,
"message": "Unsupported protocol version",
"data": {"supported": ["2025-03-26"], "requested": "2024-11-05"}
}
}
Initialization errors prevent any further communication until resolved. You'll need to adjust your client to use a compatible protocol version or find a server that supports your requirements.
Resource Errors
The resource system uses dedicated error codes for URI-related failures:
{
"jsonrpc": "2.0",
"id": 5,
"error": {
"code": -32002,
"message": "Resource not found",
"data": {"uri": "file:///nonexistent.txt"}
}
}
Code -32002
specifically indicates that the requested resource doesn't exist or can't be accessed. This happens when working with file systems, databases, or external APIs where the requested data isn't available.
Tool Error Pattern
Here's where MCP gets interesting—tool execution failures don't use standard error objects. Instead, failed tool calls return a successful response with an isError
flag:
{
"jsonrpc": "2.0",
"id": 4,
"result": {
"content": [
{"type": "text", "text": "Failed to fetch weather data: API key invalid"}
],
"isError": true
}
}
This design separates protocol errors from application errors. The request was processed correctly at the protocol level, but the tool itself encountered issues. You need to check both standard errors and this flag to handle all failure scenarios.
Error Handling in Practice
In real MCP applications, error handling involves several layers. The TypeScript SDK exposes errors as objects with code, message, and data fields:
try {
const result = await client.request(
{ method: "resources/read", params: { uri: "file:///sample.txt" } },
ReadResourceResultSchema
);
} catch (error) {
console.error(`Error ${error.code}: ${error.message}`);
// Error -32002: Resource not found
}
The Python SDK uses exceptions:
try:
result = await session.send_request(
{"method": "resources/read", "params": {"uri": "file:///sample.txt"}},
ReadResourceResult
)
except McpError as e:
print(f"Error {e.code}: {e.message}")
# Error -32002: Resource not found
When working with MCP tools, error handling must account for both protocol errors and tool execution errors. This is a subtlety that trips up many MCP newcomers.
During development, you'll see these error codes in various contexts—in the MCP Inspector when testing servers, in client SDK exceptions when writing code, and in server logs when debugging. Recognizing common patterns saves considerable troubleshooting time.
Conclusion
MCP's error codes might seem intimidating at first, but they provide precise information about what went wrong and how to fix it. From parse errors to resource not found situations, the error system gives you specific diagnostics to troubleshoot problems efficiently.
The next time you encounter an MCP error, look at the code first—it immediately narrows down the problem category. Then check the message for specific details and the data field for additional context. With practice, you'll recognize common patterns and resolve issues more quickly.