You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Simplify error response when accessing MCP without session ID #577
Description:
Currently, when accessing the MCP Streamable HTTP server at https://host:port/mcp without providing a session ID, the server responds with the full exception stack trace and detailed error information.
Issue:
Returning the complete stack trace in the response is not user-friendly and may expose internal details unnecessarily.
Suggestion:
Instead of returning the full error, return a simple, clear message indicating there is an issue with the request headers or the session ID
Extending from this issue, I hope to refactor abs mcptransport, because i found so many responseError method in different child class, for example, why public interface McpStatelessServerTransport {
child class not extends McpServerTransport ?
The response is HTTP 500 with JSON-RPC code -32603. The body serializes the complete McpError, including stackTrace, cause, localizedMessage, and other Java exception
properties:
HTTP/1.1 500 Server ErrorContent-Type: application/json;charset=utf-8
The request should complete as a normal JSON-RPC response with the original request ID and -32601 Method not found, without serialized exception internals. For example:
DefaultMcpStatelessServerHandler.handleRequest correctly constructs an McpError using METHOD_NOT_FOUND, but propagates it with Mono.error(...).
HttpServletStatelessServerTransport.doPost blocks on that publisher, catches the exception, replaces it with INTERNAL_ERROR, and passes the exception object to its JSON error
writer. Jackson then serializes the Java exception properties.
The missing-handler branch could instead return a normal JSONRPCResponse.error(...), consistent with how errors from registered handlers are converted into JSON-RPC responses.
Confirming this is still present in 2.1.0 and on main, and that it is not specific to the session-id path: every error the servlet transports write as a JSON body goes through responseError, which does jsonMapper.writeValueAsString(mcpError) on the exception itself. HttpServletStatelessServerTransport L269, HttpServletStreamableServerTransportProvider L738, HttpServletSseServerTransportProvider L442 and L496 (2.1.0 line numbers). On the stateless transport that covers 415 (Content-Type), 400 (Accept, malformed body, unexpected message type) and the handler-failure 500s. With a default Jackson 2 mapper the body is about 20 KB with 80+ frames.
Reproduced on a Jetty 12 deployment of HttpServletStatelessServerTransport (Java 17, mcp-json-jackson2 2.1.0):
Workaround that works today: register a Jackson serializer for McpError on the mapper you pass to the transport builder, writing {"jsonrpc":"2.0","id":null,"error":{"code":…,"message":…}} from getJsonRpcError(). One note for the fix: McpSchema.JSONRPCResponse's compact constructor rejects a null id, and on these paths the id is unknown, so the envelope has to be built separately (JSON-RPC 2.0 prescribes id: null there).
Activity
JunJieLiu51520 commentedon Sep 27, 2025
Extending from this issue, I hope to refactor abs mcptransport, because i found so many responseError method in different child class, for example, why public interface McpStatelessServerTransport {
child class not extends McpServerTransport ?
quaff commentedon Sep 28, 2025
See #519
AlanBurlison commentedon Jul 1, 2026
DISCLAIMER: Codex-generated comment:
This also occurs in the SDK 2.0.0 stateless servlet transport, through a slightly different path.
Environment
HttpServletStatelessServerTransport2025-06-18The server advertises tools but not resources or prompts.
Reproduction
Actual response
The response is HTTP 500 with JSON-RPC code
-32603. The body serializes the completeMcpError, includingstackTrace,cause,localizedMessage, and other Java exceptionproperties:
{ "jsonRpcError": { "code": -32603, "message": "Failed to handle request: Missing handler for request type: resources/list" }, "cause": null, "localizedMessage": "Failed to handle request: Missing handler for request type: resources/list", "message": "Failed to handle request: Missing handler for request type: resources/list", "stackTrace": [ { "className": "io.modelcontextprotocol.spec.McpError$Builder", "methodName": "build", "fileName": "McpError.java" }, { "className": "io.modelcontextprotocol.server.transport.HttpServletStatelessServerTransport", "methodName": "doPost", "fileName": "HttpServletStatelessServerTransport.java" } ] }Expected response
The request should complete as a normal JSON-RPC response with the original request ID and
-32601 Method not found, without serialized exception internals. For example:{ "jsonrpc": "2.0", "id": 1, "error": { "code": -32601, "message": "Method not found: resources/list" } }Apparent cause
DefaultMcpStatelessServerHandler.handleRequestcorrectly constructs anMcpErrorusingMETHOD_NOT_FOUND, but propagates it withMono.error(...).HttpServletStatelessServerTransport.doPostblocks on that publisher, catches the exception, replaces it withINTERNAL_ERROR, and passes the exception object to its JSON errorwriter. Jackson then serializes the Java exception properties.
The missing-handler branch could instead return a normal
JSONRPCResponse.error(...), consistent with how errors from registered handlers are converted into JSON-RPC responses.Add a stateless server for MCP 2026-07-28
Add a stateless server for MCP 2026-07-28
Modern stateless server for MCP 2026-07-28 (#1170)
IdentityOverflow commentedon Nov 4, 2026
Confirming this is still present in 2.1.0 and on
main, and that it is not specific to the session-id path: every error the servlet transports write as a JSON body goes throughresponseError, which doesjsonMapper.writeValueAsString(mcpError)on the exception itself.HttpServletStatelessServerTransportL269,HttpServletStreamableServerTransportProviderL738,HttpServletSseServerTransportProviderL442 and L496 (2.1.0 line numbers). On the stateless transport that covers 415 (Content-Type), 400 (Accept, malformed body, unexpected message type) and the handler-failure 500s. With a default Jackson 2 mapper the body is about 20 KB with 80+ frames.Reproduced on a Jetty 12 deployment of
HttpServletStatelessServerTransport(Java 17, mcp-json-jackson2 2.1.0):returns 415 with
{"cause":null,"stackTrace":[.... Minimal reproducer without a server:Workaround that works today: register a Jackson serializer for
McpErroron the mapper you pass to the transport builder, writing{"jsonrpc":"2.0","id":null,"error":{"code":…,"message":…}}fromgetJsonRpcError(). One note for the fix:McpSchema.JSONRPCResponse's compact constructor rejects a nullid, and on these paths the id is unknown, so the envelope has to be built separately (JSON-RPC 2.0 prescribesid: nullthere).