{"record":{"id":"112665c0314a2620","repo":"googleapis/mcp-toolbox","slug":"mcp-name-header-value-s-does-not-match-body-val","errorCode":null,"errorMessage":"Mcp-Name header value '%s' does not match body value '%s'","messagePattern":"Mcp-Name header value '(.+?)' does not match body value '(.+?)'","errorType":"error_code","errorClass":"NewHeaderMismatchedError","httpStatus":null,"severity":"error","filePath":"internal/server/mcp/v20260728/method.go","lineNumber":117,"sourceCode":"\n// validateHeader checks the header of every requests\n// Toolbox do not check for `Mcp-Param-{Name}` header since we are not\n// implementing custom headers from parameters\n// Do not need to check for Base64-encoding or invalid characters since we are\n// only checking `mcp-method` and `mcp-name`\nfunc validateHeader(id jsonrpc.RequestId, header http.Header, method, name string) (any, error) {\n\t// stdio transport will not have header\n\tif header == nil {\n\t\treturn nil, nil\n\t}\n\theaderMethod := header.Get(\"mcp-method\")\n\tif headerMethod != method {\n\t\terr := fmt.Errorf(\"Mcp-Method header value '%s' does not match body value '%s'\", headerMethod, method)\n\t\treturn jsonrpc.NewHeaderMismatchedError(id, err), err\n\t}\n\theaderName := header.Get(\"mcp-name\")\n\tif headerName != name {\n\t\terr := fmt.Errorf(\"Mcp-Name header value '%s' does not match body value '%s'\", headerName, name)\n\t\treturn jsonrpc.NewHeaderMismatchedError(id, err), err\n\t}\n\treturn nil, nil\n}\n\n// getResultMetadata append the resultMetaObject on existing metadata\nfunc getResultMetadata(ctx context.Context, curMeta map[string]any) (map[string]any, error) {\n\tv, err := util.ToolboxVersionFromContext(ctx)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tresMetaObj := ResultMetaObject{\n\t\tServerInfo: Implementation{\n\t\t\tBaseMetadata: BaseMetadata{\n\t\t\t\tName: SERVER_NAME,\n\t\t\t},\n\t\t\tVersion: v,","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/server/mcp/v20260728/method.go#L99-L135","documentation":"After verifying Mcp-Method, validateHeader also checks that the `Mcp-Name` header matches the entity name in the request body (e.g. the tool name in a tools/call request). A mismatch is treated as a potential header-injection or routing integrity problem and rejected with a HeaderMismatchedError (internal/server/mcp/v20260728/method.go:117).","triggerScenarios":"A tools/call request where the `Mcp-Name` header does not equal `params.name` in the body (e.g. header says `my_tool` but body calls `my_tool_v2`). Also triggered by prompts/get with mismatched prompt name; other handlers pass an empty name which always matches.","commonSituations":"Clients caching headers from a previous call and reusing them; wrappers around the MCP client that set Mcp-Name once at startup; renaming a tool in the toolbox config without updating the calling application; proxies injecting or rewriting the header.","solutions":["Set Mcp-Name to exactly the tool (or prompt) name in the request params for each call.","Ensure the header is generated per-request from the same value used in the body, not cached.","Confirm the tool name in your client matches the tool's current name in the toolbox config (tool names are snake_case).","If a proxy strips/rewrites headers, add Mcp-Name to its passthrough list."],"exampleFix":"// before\nheaders.Set(\"Mcp-Name\", \"list_tables\")\nbody := `{\"method\":\"tools/call\",\"params\":{\"name\":\"run_query\"}}`\n// after\nheaders.Set(\"Mcp-Name\", \"run_query\")\nbody := `{\"method\":\"tools/call\",\"params\":{\"name\":\"run_query\"}}`","handlingStrategy":"validation","validationCode":"function validateMcpNameHeader(headers, body) {\n  const parsed = JSON.parse(body);\n  if (parsed.method === 'tools/call' && headers.get('Mcp-Name') !== parsed.params.name) {\n    throw new Error(`Mcp-Name header '${headers.get('Mcp-Name')}' != params.name '${parsed.params.name}'`);\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  const res = await callTool(name, args);\n  if (res.error && res.error.message.includes('Mcp-Name header')) {\n    // rebuild headers from current tool name and retry once\n    return callTool(name, args);\n  }\n} catch (e) { console.error('tools/call failed:', e); }","preventionTips":["Build Mcp-Name per-request from the exact params.name value.","Never cache headers across calls to different tools.","Keep client tool registries in sync with the toolbox config after renames.","Add proxy passthrough rules for Mcp-Name."],"tags":["mcp","http-header","request-validation","go"],"backgroundTag":"http-header-body-mismatch","analyzedSha":"8cc6e09de2ad7b8bffc77751799585a1401a48eb","analyzedAt":"2026-09-05T01:10:36.887Z","contentChangedAt":"2026-09-05T01:10:36.887Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}