googleapis/mcp-toolbox · error · NewHeaderMismatchedError
Mcp-Method header value '%s' does not match body value '%s'
Error message
Mcp-Method header value '%s' does not match body value '%s'
What it means
The MCP server validates that the `Mcp-Method` HTTP header exactly matches the JSON-RPC `method` field of the request body. A mismatch indicates the request may be tampered with or routed incorrectly, so the server rejects it with a jsonrpc HeaderMismatchedError before processing. This is part of a header-integrity check in validateHeader (internal/server/mcp/v20260728/method.go:112).
Source
Thrown at internal/server/mcp/v20260728/method.go:112
metaErr := fmt.Errorf("_meta error: missing required fields in request metadata")
return jsonrpc.NewError(id, jsonrpc.INVALID_PARAMS, metaErr.Error(), nil), metaErr
}
return nil, nil
}
// validateHeader checks the header of every requests
// Toolbox do not check for `Mcp-Param-{Name}` header since we are not
// implementing custom headers from parameters
// Do not need to check for Base64-encoding or invalid characters since we are
// only checking `mcp-method` and `mcp-name`
func validateHeader(id jsonrpc.RequestId, header http.Header, method, name string) (any, error) {
// stdio transport will not have header
if header == nil {
return nil, nil
}
headerMethod := header.Get("mcp-method")
if headerMethod != method {
err := fmt.Errorf("Mcp-Method header value '%s' does not match body value '%s'", headerMethod, method)
return jsonrpc.NewHeaderMismatchedError(id, err), err
}
headerName := header.Get("mcp-name")
if headerName != name {
err := fmt.Errorf("Mcp-Name header value '%s' does not match body value '%s'", headerName, name)
return jsonrpc.NewHeaderMismatchedError(id, err), err
}
return nil, nil
}
// getResultMetadata append the resultMetaObject on existing metadata
func getResultMetadata(ctx context.Context, curMeta map[string]any) (map[string]any, error) {
v, err := util.ToolboxVersionFromContext(ctx)
if err != nil {
return nil, err
}
resMetaObj := ResultMetaObject{View on GitHub (pinned to 8cc6e09de2)
Solutions
- Set the Mcp-Method header to exactly the JSON-RPC method string sent in the body (e.g. Mcp-Method: tools/list with "method":"tools/list").
- If behind a proxy/load balancer, configure it to pass through the Mcp-Method and Mcp-Name headers unmodified.
- Regenerate the request with an up-to-date MCP client SDK so header and body are produced together.
- For local stdio usage, omit headers entirely; validation is skipped when header is nil.
Example fix
// before
curl -X POST http://127.0.0.1:5000/mcp -H 'Mcp-Method: tools/call' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
// after
curl -X POST http://127.0.0.1:5000/mcp -H 'Mcp-Method: tools/list' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' Defensive patterns
Strategy: validation
Validate before calling
function validateMcpMethodHeader(headers, body) {
const parsed = JSON.parse(body);
if (headers.get('Mcp-Method') !== parsed.method) {
throw new Error(`Mcp-Method header '${headers.get('Mcp-Method')}' != body method '${parsed.method}'`);
}
} Try / catch
try {
const res = await fetch(mcpUrl, { headers: { 'Mcp-Method': method, 'Mcp-Name': name }, body });
const payload = await res.json();
if (payload.error && payload.error.code === -32000) { // HeaderMismatchedError class
console.error('Header/body mismatch:', payload.error.message);
}
} catch (e) { console.error('request failed', e); } Prevention
- Always generate the Mcp-Method header from the same variable used for the body's method field.
- Configure proxies to pass Mcp-* headers through unmodified.
- Prefer official MCP client SDKs over hand-built HTTP requests.
- Add a pre-send assertion in tests comparing header and body method.
When it happens
Trigger: Sending a streamable-HTTP request to tools/list, tools/call, prompts/list, prompts/get, server/discover, or groups/list endpoints where the `Mcp-Method` header value differs from the body's `method` field (e.g. header `tools/call` with body method `tools/list`). A nil header (stdio) skips validation.
Common situations: Reverse proxies or middleware rewriting/stripping headers; client SDKs generating the header from a stale or hardcoded value; manually constructed curl requests where header and body disagree; HTTP/2 or proxy layer lowercasing or mangling header names.
Related errors
- Mcp-Name header value '%s' does not match body value '%s'
- invalid notification request: %w
- INVALID_REQUEST
- INTERNAL_ERROR
- METHOD_NOT_FOUND
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/05b5c7df2e279d50.
Report an issue: GitHub.