← All articles

MCP Error Codes: Complete Troubleshooting Guide

July 8, 2026·18 min read·MCPForge

MCP Error Codes Quick Reference

When an MCP request fails, the JSON-RPC layer returns a structured error object. The table below maps every standard error code to its failure layer and the first thing you should check. For Appwrite-specific failures, pair the code lookup with the Appwrite MCP troubleshooting guide.

Standard JSON-RPC Error Codes Used by MCP

Error CodeStandard MeaningFailure LayerFirst Check
-32700Parse ErrorTransport / SerializationMalformed JSON in request or response
-32600Invalid RequestProtocolMissing jsonrpc, method, or id fields
-32601Method Not FoundProtocol / CapabilityMethod name typo or capability not declared
-32602Invalid ParamsProtocol / SchemaCheck error.data for validation details
-32603Internal ErrorServer-sideServer logs / stderr for stack trace
-32000 to -32099Server-Defined (implementation-specific)VariesRead error.message, error.data, and implementation docs

Critical: Codes -32000 through -32099 have no universal MCP-defined meanings. The number alone tells you almost nothing. Always read the full error object and your implementation's documentation.

Common MCP Error Messages and What They Usually Indicate

Error MessageWhat It Usually IndicatesFirst Diagnostic Step
Connection ClosedTransport dropped before response arrivedCheck server process health and stderr
Request Timed OutResponse not received within client timeoutCheck server startup time and tool execution duration
Method Not FoundServer doesn't recognize the called methodVerify capability negotiation in initialize response
Unsupported Protocol VersionClient and server disagree on MCP versionCheck protocolVersion in initialize handshake
Initialization Failedinitialize / initialized handshake did not completeInspect both sides of the handshake in logs
Invalid Session IDHTTP session token missing or expiredCheck Mcp-Session-Id header and session lifecycle
Failed to ConnectClient cannot reach server process or endpointVerify command path, port, or URL
Server Process Exitedstdio server process terminated unexpectedlyCheck exit code and stderr for crash reason
Tool Not Foundtools/call references a tool not in tools/listRe-run tools/list; check server registration logic
Tool Execution ErrorTool ran but returned isError: trueRead tool result content array for the error detail
Unauthorized / 401Missing or invalid authentication credentialCheck Bearer token, OAuth flow, or API key
Forbidden / 403Authenticated but lacks permissionCheck scope, role, or resource-level authorization
Rate Limited / 429Too many requests to server or upstream APIImplement backoff; check upstream API quota

How MCP Errors Are Structured

MCP uses JSON-RPC 2.0 as its wire protocol. Every error response follows this structure:

json
{
  "jsonrpc": "2.0",
  "id": "request-id-123",
  "error": {
    "code": -32603,
    "message": "Internal error",
    "data": {
      "details": "TypeError: Cannot read properties of undefined (reading 'execute')",
      "stack": "..."
    }
  }
}

Three fields matter:

  • code — an integer that classifies the error category. Use it to route your diagnosis, not to determine the exact cause.
  • message — a short human-readable string. For server-defined codes (-32000 to -32099), this is often more diagnostic than the code itself.
  • data — optional, implementation-defined. Can contain stack traces, validation details, upstream error bodies, or structured metadata. Always inspect this field — it is frequently the fastest path to a fix.

Want to analyze your API security?

Import your OpenAPI spec and generate a Security Report automatically.

MCP Error -32700: Parse Error

What it means: The server (or client) received a message it could not parse as valid JSON.

Why it happens:

  • Truncated message due to a transport buffer or encoding issue
  • Binary data injected into a stdio stream that expects newline-delimited JSON
  • A server writing non-JSON to stdout before the MCP handshake (startup banners, debug prints)

How to fix it:

  1. Capture raw transport bytes. For stdio, redirect server stdout to a file and inspect it.
  2. Look for non-JSON content at the start of the stream — startup log lines are the most common culprit.
  3. Ensure your server only writes valid JSON-RPC objects to stdout. All diagnostic output must go to stderr.
  4. Check for encoding mismatches (UTF-16 vs UTF-8).
bash
# Capture raw stdio output to inspect
my-mcp-server 2>/dev/null | head -c 500 | cat -v

MCP Error -32600: Invalid Request

What it means: The JSON parsed correctly, but the object does not conform to the JSON-RPC 2.0 request structure.

Common causes:

  • Missing jsonrpc: "2.0" field
  • Missing or null method field
  • Sending a batch request to a server that doesn't support batching
  • Client SDK bug producing malformed envelopes

How to fix it: Enable verbose logging in your client SDK to capture outgoing raw messages. Compare against the MCP specification. This error almost always points to a client-side or SDK-level issue.


MCP Error -32601: Method Not Found

What it means: The server received a valid request but does not recognize the method value.

Common causes in MCP:

  • Calling tools/call before the server declared tools capability in its initialize response
  • Typo in a custom method name
  • Client and server running incompatible MCP spec versions where method names changed
  • Server failing to register handlers for standard methods

How to fix it:

  1. Check the server's initialize response — specifically the capabilities object. If tools is absent, the server does not support tool calls.
  2. Confirm the method string exactly matches the MCP spec (tools/list, tools/call, resources/read, etc.).
  3. If you see this during protocol negotiation, cross-check the MCP spec version both sides declare.

MCP Error -32602: Invalid Params

What it means: The method was found, but the parameters failed validation.

Common causes in MCP:

  • Missing required fields in a tools/call request (e.g., missing name)
  • Tool input that doesn't match the tool's declared JSON Schema
  • Sending the wrong data type for a parameter
  • In some implementations: an initialize request declaring a protocol version the server doesn't support — you may see this surfaced as -32602 with a message like "Unsupported protocol version", though this is implementation-specific behavior, not a redefinition of the standard code

How to fix it:

  1. Check error.data — most MCP servers include the specific validation failure there.
  2. Retrieve the tool's input schema via tools/list and validate your payload against it before calling.
  3. If the error occurs during initialize, compare the protocolVersion strings on both sides.
json
// Example tools/call with correct structure
{
  "jsonrpc": "2.0",
  "id": "1",
  "method": "tools/call",
  "params": {
    "name": "get_weather",
    "arguments": {
      "city": "London"
    }
  }
}

MCP Error -32603: Internal Error

What it means: The server crashed or encountered an unhandled exception while processing the request.

This is always a server-side problem. The client sent a valid request; the server failed to handle it.

Common causes:

  • Unhandled exception in tool handler code
  • Missing environment variable causing a null reference
  • Crashed database connection or external dependency
  • Out-of-memory condition
  • Bug in the MCP server SDK being used

How to fix it:

  1. Check server stderr immediately — most SDKs print the full stack trace there.
  2. Look at error.data in the response for an embedded stack trace.
  3. Reproduce the call in isolation using MCP Inspector to rule out client-side interference.
  4. Add try/catch around tool handler logic and return structured errors via isError: true in the tool result rather than letting exceptions propagate to the JSON-RPC layer.

See the detailed -32603 troubleshooting guide for specific fixes by server framework.


MCP Error -32000 to -32099: Server-Defined Errors

The JSON-RPC 2.0 specification reserves codes -32000 through -32099 for implementation use. The MCP specification does not standardize specific meanings within this range. Different clients and servers assign their own codes.

This means diagnosing these errors requires:

  1. Reading the error.message string (more diagnostic than the number)
  2. Inspecting error.data for structured details
  3. Checking your specific client's documentation or source code
  4. Reviewing server logs to find what triggered the error

MCP Error -32000: "Connection Closed" (Implementation-Specific)

In Claude Desktop, Cursor, and several other MCP clients, -32000 is commonly emitted with the message "Connection closed" when the underlying transport dropped before the response was delivered. This is not a universal MCP standard definition — it is a convention adopted by those implementations.

Typical causes when this message appears:

  • The stdio server process exited prematurely
  • The HTTP connection was reset or timed out at the network layer
  • A client-side connection pool recycled the connection
  • The server crashed during request processing

How to diagnose:

  1. Check whether the server process is still running after the error
  2. Review server stderr for crash output or unexpected exit
  3. For HTTP transport, check network infrastructure (load balancer timeouts, proxy resets)

For a step-by-step fix guide, see How to Fix MCP Error -32000: Connection Closed.

MCP Error -32001: "Request Timed Out" (Implementation-Specific)

Similarly, -32001 is commonly used to signal request timeout in some MCP clients. This is again implementation-specific — not a universally standardized MCP error code.

Typical causes when this message appears:

  • Tool execution taking longer than the client's configured timeout
  • Slow server startup causing initialization to exceed the timeout window
  • Blocking I/O in a tool handler with no async handling
  • Large data transfers over slow connections

How to diagnose:

  1. Measure actual tool execution time vs. client timeout setting
  2. Check if the issue is isolated to specific tools or all calls
  3. Review server-side performance for the slow path

For detailed fixes, see How to Fix MCP Error -32001: Request Timed Out.


Protocol Errors vs Tool Execution Errors

One of the most important conceptual distinctions in MCP debugging:

Error TypeReturned AsTypical CauseVisible to ModelCorrect Fix
Protocol ErrorJSON-RPC error object (with code)Bad request, server crash, transport failureNo — client handles itFix the request, transport, or server
Tool Execution ErrorNormal tools/call result with isError: trueTool logic failed (API error, bad input, exception)Yes — model sees the error contentFix the tool logic; return structured error messages

Why this matters in practice:

If your tool calls a downstream API that returns a 404, the correct behavior is to return a successful JSON-RPC response containing a tool result where isError: true and the content describes the failure. The model can then reason about it and potentially retry or inform the user.

If you instead throw an unhandled exception that becomes a -32603 Internal Error, the model sees nothing — the client receives a protocol-level failure and typically cannot inform the model of what went wrong.

json
// Correct: tool execution error returned to the model
{
  "jsonrpc": "2.0",
  "id": "1",
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Error: The requested resource was not found (404). Please verify the ID and try again."
      }
    ],
    "isError": true
  }
}

MCP Errors by Failure Layer

Before diving into specific error codes, identify which layer failed. This dramatically narrows the search space.

Failure LayerCommon SymptomsWhat to CheckRecommended Test
Process Launch"Server Process Exited", "Failed to Connect"Command path, env vars, permissions, dependenciesRun the server command manually in a terminal
TransportParse errors, connection resets, -32000stdio vs HTTP config, port availability, proxy settingscurl for HTTP; raw pipe test for stdio
Initialization"Initialization Failed", -32601 on first callinitialize / initialized handshake logsMCP Inspector initialization test
Session"Invalid Session ID", 404 on requestsMcp-Session-Id header presence and validityReplay request with correct session header
Authentication401 Unauthorized, 403 ForbiddenToken validity, OAuth configuration, scopescurl -H "Authorization: Bearer <token>"
JSON-RPC Protocol-32700, -32600, -32602Raw request/response payload structureEnable SDK verbose logging
Tool Discovery"Tool Not Found", empty tool listtools/list response, server registration codeCall tools/list directly via MCP Inspector
Tool ExecutionisError: true in result, -32603Tool handler logs, upstream API responsesCall the tool in isolation via MCP Inspector
Upstream APITool errors mentioning external servicesAPI credentials, rate limits, endpoint availabilityCall the upstream API directly with the same params
Server InfrastructureIntermittent failures, slow responsesMemory, CPU, disk, network at server hostServer monitoring metrics

How to Diagnose Any MCP Error

Follow this flow regardless of the error code. Each step narrows the failure layer.

Step 1 — Capture the complete error object

Get the full JSON including code, message, and data. Many developers only look at the message string and miss critical detail in data.

Step 2 — Verify the server process starts

bash
# For stdio servers — run the command directly
node /path/to/my-mcp-server/index.js
# Should output the initialize response when you send the handshake
# Any crash here is a process launch failure

If the process exits immediately, the failure is at the launch layer. Fix dependencies, environment variables, or file paths before investigating anything else.

Step 3 — Identify the transport

  • stdio: The client spawns the server as a child process. stderr is your primary log channel.
  • Streamable HTTP: The server runs independently. Check the HTTP endpoint reachability and server logs separately.

Step 4 — Read logs from both sides

For Claude Desktop on macOS:

bash
tail -f ~/Library/Logs/Claude/mcp*.log

For stdio servers, server stderr typically flows into the client's log. For HTTP servers, check your server process logs directly.

Step 5 — Verify initialization completes

The initializeinitialized handshake must complete before any other method call. If you see -32601 on the very first real request, the handshake likely failed silently. Look for the initialize response in logs and confirm the capabilities object is present.

Step 6 — Check authentication and session state

For HTTP-based MCP servers:

  • Confirm Bearer token is present and not expired
  • Confirm Mcp-Session-Id header is sent on every request after the session is established
  • Check OAuth token scopes match required permissions

Step 7 — Test tool discovery

bash
# Using MCP Inspector (npx)
npx @modelcontextprotocol/inspector node /path/to/server.js

Call tools/list and confirm the tool you're trying to call appears in the response with the expected schema.

Step 8 — Reproduce the failing tool call in isolation

Using MCP Inspector, call the specific tool with the exact same arguments the client would send. This isolates whether the failure is in the client or the server.

Step 9 — Fix the failing layer and verify recovery

Don't move to the next layer until you've confirmed the current one is healthy. A process that crashes at startup will produce misleading transport errors if you skip layer 2.


MCP Error Troubleshooting Matrix

Error or SymptomLikely CauseHow to VerifyFixDetailed Guide
-32700 Parse ErrorNon-JSON in transport streamCapture raw stdout; look for startup logs before JSONMove all non-JSON output to stderr
-32600 Invalid RequestMalformed JSON-RPC envelopeLog raw outgoing messages from clientFix client SDK or request construction
-32601 Method Not FoundCapability not declared or wrong method nameCheck initialize response capabilitiesDeclare capability in server; fix method name
-32602 Invalid ParamsSchema validation failureInspect error.data fieldFix argument structure to match tool schema
-32603 Internal ErrorUnhandled server exceptionCheck server stderr for stack traceAdd error handling in tool handlersFix Guide
-32000 / Connection ClosedServer process exited or transport resetCheck server process still runningFix crash cause; restart serverFix Guide
-32001 / Request Timed OutTool too slow or server overloadedMeasure tool execution timeOptimize tool; increase timeout if configurableFix Guide
Failed to ConnectWrong path, port, or commandRun server command manuallyFix client config (command, args, URL)Troubleshooting Guide
Server Process ExitedMissing dependency, bad env varRun server manually; check exit codeInstall deps; set env varsConnection Guide
Initialization FailedHandshake timeout or version mismatchCheck both sides of handshake in logsAlign protocol versions; fix server startup time
Invalid Session IDSession expired or header missingInspect HTTP headers on failing requestRe-initialize session; fix header propagation
Unsupported Protocol VersionVersion string mismatch in initializeCompare protocolVersion in request and responseUpdate client or server to compatible version
Tool Not FoundTool not registered or name mismatchCall tools/listFix registration logic or correct tool name
isError: true in resultTool logic failure (not protocol failure)Read content array in tool resultFix tool business logic or downstream API call
401 UnauthorizedMissing or expired tokenReplay request with valid tokenRefresh token; fix OAuth configuration
403 ForbiddenInsufficient scope or permissionsCheck token scopes vs required permissionsUpdate OAuth scopes or fix authorization logic
429 Rate LimitedToo many requestsCheck retry-after header; review request rateImplement exponential backoff; cache results

Testing MCP Servers Independently

The most reliable way to isolate whether an error is client-caused or server-caused is to test the server directly, bypassing the client entirely.

MCP Inspector

MCP Inspector is the official interactive debugger for MCP servers:

bash
# Test a stdio server
npx @modelcontextprotocol/inspector node ./my-server/index.js

# Test with environment variables
npx @modelcontextprotocol/inspector -e API_KEY=your_key node ./my-server/index.js

# Test an HTTP server
npx @modelcontextprotocol/inspector --url http://localhost:3000/mcp

Inspector shows raw JSON-RPC messages, server stderr output in real time, and lets you manually trigger initialize, tools/list, and individual tools/call requests. If the tool works in Inspector but fails in Claude Desktop, the problem is in the client configuration, not the server.

You can also use the MCPForge online server tester to validate HTTP-based MCP servers without installing anything locally.

Raw stdio Test

For quick verification without Inspector:

bash
# Send a minimal initialize request via echo
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' | node ./my-server/index.js

If you get a valid initialize response back, the server starts and the protocol layer works. If you get nothing or a crash, the problem is at the process or transport layer.


Authentication and Authorization Errors

For HTTP-based MCP deployments, authentication failures surface as HTTP status codes before any JSON-RPC error is even constructed. Don't confuse them:

HTTP StatusWhat It Means in MCPHow to Fix
401 UnauthorizedNo valid credential providedAdd or refresh Bearer token; fix OAuth flow
403 ForbiddenCredential valid but lacks permissionAdd required scope; fix resource authorization
429 Too Many RequestsRate limit exceededBack off and retry; cache repeated calls
503 Service UnavailableServer overloaded or starting upRetry with backoff; check server health

These are HTTP-layer failures, not JSON-RPC errors. Your MCP client will typically surface them as connection failures or initialization failures rather than a numeric JSON-RPC error code.

For OAuth-based MCP servers, the most common mistake is requesting an access token with insufficient scopes during the OAuth authorization flow. Always verify the granted scopes match what the server requires.


Streamable HTTP-Specific Errors

The Streamable HTTP transport (the current recommended HTTP transport in MCP) introduces session management that stdio servers don't have. Additional failure modes:

Session establishment failures:

  • The first initialize POST must succeed and return an Mcp-Session-Id header
  • Subsequent requests must include this header — missing it causes session-not-found errors
  • Sessions can expire; clients must re-initialize on expiry

SSE stream errors:

  • For servers using SSE for server-to-client streaming, dropped connections cause partial responses
  • Implement reconnection logic on the client side
  • Verify the server sends proper SSE data: prefixes and \n\n terminators

Proxy and infrastructure issues:

  • Load balancers with short HTTP timeouts will kill long-running tool calls
  • Ensure your infrastructure allows HTTP connections to remain open for the duration of your longest expected tool execution
  • If using NGINX, set proxy_read_timeout appropriately

For production Streamable HTTP deployments, see Running MCP in Production for infrastructure configuration guidance.


Prevention Best Practices

Most MCP errors are preventable. Apply these at build time:

Server implementation:

  • Always send all non-JSON diagnostic output to stderr, never stdout (for stdio servers)
  • Wrap every tool handler in try/catch; return isError: true results instead of letting exceptions propagate
  • Declare only capabilities your server actually implements in the initialize response
  • Validate all tool input arguments at the start of each handler using your declared JSON Schema
  • Set explicit timeouts on all upstream API calls inside tool handlers

Transport and infrastructure:

  • For stdio: confirm environment variables and dependencies before deploying to a client
  • For HTTP: configure infrastructure timeouts to exceed your maximum expected tool execution time
  • Implement health check endpoints on HTTP servers so load balancers don't route to unhealthy instances

Development workflow:

  • Test every server with MCP Inspector before connecting to Claude Desktop or Cursor
  • Log the full JSON-RPC request and response at DEBUG level during development
  • Use the MCPForge server tester for HTTP servers before production deployment
  • Pin your MCP SDK version and test explicitly when upgrading

Client configuration:

  • Double-check command paths, working directories, and environment variable names in client config files
  • Use absolute paths for stdio server commands to avoid PATH resolution issues
  • Test configuration changes in Claude Desktop by checking the MCP logs immediately after restart

Visual Architecture: Where MCP Errors Originate

┌─────────────────────────────────────────────────────────────┐
│                     MCP Client                              │
│   (Claude Desktop, Cursor, custom client)                   │
│                                                             │
│   Client config error ──► "Failed to Connect"              │
│   Client timeout      ──► "-32001" (implementation-specific)│
└──────────────────┬──────────────────────────────────────────┘
                   │ Transport
        ┌──────────┴──────────┐
        │ stdio               │ Streamable HTTP
        │                     │
   Process launch        HTTP layer
   failure ──► -32000    401/403/429
   Parse error ──► -32700│
        │                     │
        └──────────┬──────────┘
                   │ JSON-RPC Layer
                   │
              ┌────┴────┐
              │  MCP    │
              │ Server  │
              │         │
    Protocol errors:    Tool execution:
    -32600 Invalid Req  isError: true
    -32601 No Method    (model sees this)
    -32602 Bad Params
    -32603 Internal Err
    -320xx Server-Defined
              └────┬────┘
                   │
            Upstream APIs
            (429, 503, etc. wrapped
             in tool results)

Key Takeaways

  • Read the full error objectcode tells you the category; message and data tell you the cause
  • -32000 to -32099 are not standardized — meanings vary by implementation; always check the message string
  • Protocol errors and tool execution errors are different — tool failures belong in isError: true results, not JSON-RPC error responses
  • Identify the failure layer first — process, transport, protocol, auth, or tool — before investigating specific codes
  • MCP Inspector is the fastest isolation tool — if it works in Inspector, the server is fine and the problem is client-side
  • Most -32603 errors are fixable — add error handling in your tool handlers and stop letting exceptions surface as protocol failures

Frequently Asked Questions

What are MCP error codes?

MCP error codes are integer codes returned inside JSON-RPC 2.0 error objects when a request fails. They follow the JSON-RPC 2.0 standard: codes from -32700 to -32603 are standard protocol errors, codes from -32000 to -32099 are reserved for server-defined errors, and each implementation may assign its own meanings within that range.

What does MCP error -32000 mean?

-32000 falls inside the server-defined range (-32000 to -32099), meaning its interpretation depends entirely on the server or client implementation. In Claude Desktop and several other MCP clients it is commonly associated with 'Connection Closed', but this is not a universal MCP standard definition. Always check the accompanying error message, the data field, and your client or server logs to determine the real cause.

What does MCP error -32001 mean?

Like -32000, the code -32001 sits in the server-defined range. It is commonly reported as 'Request Timed Out' in some MCP clients, but this meaning is implementation-specific, not mandated by the MCP or JSON-RPC specification. Treat it as a hint and verify with logs and the full error object.

What does MCP error -32601 mean?

-32601 is the standard JSON-RPC 'Method Not Found' error. In MCP this typically means the client called a method (such as tools/call or resources/read) that the server does not recognize or has not registered. Check for typos in method names, version mismatches, or missing capability declarations in the server's initialize response.

What does MCP error -32602 mean?

-32602 is the standard JSON-RPC 'Invalid Params' error. The server received the method but the parameters were missing, malformed, or failed schema validation. Inspect the error.data field for the specific validation message. In protocol negotiation contexts, an unsupported protocol version is sometimes surfaced through this code, depending on the implementation.

What does MCP error -32603 mean?

-32603 is the standard JSON-RPC 'Internal Error' code. It signals an unexpected server-side failure — an unhandled exception, a crashed dependency, or a misconfigured runtime. The error.data field usually contains a stack trace or error message. Check server logs immediately; this error is almost always a server-side bug or misconfiguration.

Are -32000 error codes standardized by MCP?

No. The range -32000 to -32099 is reserved for server-defined errors by the JSON-RPC 2.0 specification, and MCP inherits this convention. Specific codes within that range (like -32000 or -32001) have no universal MCP-defined meaning. Different clients and servers assign their own meanings, so always rely on the error message and your implementation's documentation.

What is the difference between a protocol error and a tool execution error?

A protocol error is returned as a JSON-RPC error object (with a code field) when the request itself cannot be processed — wrong method, bad params, server crash. A tool execution error occurs when the tool ran successfully at the protocol level but the tool's own logic failed. Tool failures should be returned as a normal tools/call result with isError: true and an error message in the content array, not as a JSON-RPC error response.

Where can I find MCP server logs?

For stdio servers, stderr output is the primary log channel — check your client's log directory (for Claude Desktop this is ~/Library/Logs/Claude/ on macOS). For Streamable HTTP servers, check your server process logs or container stdout/stderr. MCP Inspector also surfaces server stderr in real time during interactive debugging.

How do I debug an unknown MCP error?

Start by capturing the full JSON-RPC error object including code, message, and data. Check whether the server process started at all, then identify the transport layer. Read client logs and server stderr. Test the server independently with MCP Inspector to isolate whether the problem is in the client, transport, protocol, or tool logic.

Can MCP Inspector diagnose MCP errors?

Yes. MCP Inspector is the official interactive testing tool for MCP servers. It lets you connect directly to a server, exercise the initialization handshake, list tools, and call individual tools — all while showing raw JSON-RPC messages and server stderr. This makes it ideal for isolating whether an error is caused by the client, the transport, or the server itself.

Check your MCP security posture

Generate a Security Score, detect risky tools, and review permissions before exposing APIs to AI agents.