siyuan-note/siyuan · error
property %q: x-mcp-header value %q is not a valid HTTP field
Error message
property %q: x-mcp-header value %q is not a valid HTTP field name
What it means
Thrown by validateParamHeaderAnnotations when the x-mcp-header string fails validHTTPFieldName: every character must be a visible VCHAR token per RFC 7230 (ASCII letters, digits, or one of !#$%&'*+-.^_`|~), and no character may exceed U+007F. This prevents malformed or injected header names from reaching the HTTP backend.
Source
Thrown at kernel/mcp/tools/validation.go:250
continue
}
path := propertyName
if prefix != "" {
path = prefix + "." + propertyName
}
if rawHeader, exists := property["x-mcp-header"]; exists {
header, ok := rawHeader.(string)
if !ok || header == "" {
return fmt.Errorf(`property %q: x-mcp-header must be a non-empty string`, path)
}
propertyType, _ := property["type"].(string)
if propertyType != "string" && propertyType != "integer" && propertyType != "boolean" {
return fmt.Errorf(
`property %q: x-mcp-header can only be applied to primitive types (integer, string, boolean), got %q`,
path, propertyType)
}
if !validHTTPFieldName(header) {
return fmt.Errorf(`property %q: x-mcp-header value %q is not a valid HTTP field name`, path, header)
}
normalized := strings.ToLower(header)
if seen[normalized] {
return fmt.Errorf(`property %q: duplicate x-mcp-header value %q`, path, header)
}
seen[normalized] = true
}
nested, _ := property["properties"].(map[string]any)
if err := walk(nested, path); err != nil {
return err
}
}
return nil
}
return walk(properties, "")
}
func validHTTPFieldName(name string) bool {View on GitHub (pinned to 251596fc0d)
Solutions
- Use a valid RFC 7230 token: ASCII letters, digits, and hyphens only, no spaces or colons (e.g. "X-Request-Id").
- Strip whitespace and any trailing colon before setting the value.
- Avoid non-ASCII characters in header names — HTTP field names are token-only.
Example fix
// before
{"x-mcp-header": "X Custom Header:"}
// after
{"x-mcp-header": "X-Custom-Header"} Defensive patterns
Strategy: validation
Validate before calling
func validToken(name string) bool {
if name == "" { return false }
for _, r := range name {
if r > 127 { return false }
ok := (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') || (r >= '0' && r <= '9') ||
strings.ContainsRune("!#$%&'*+-.^_`|~", r)
if !ok { return false }
}
return true
} Prevention
- Use ASCII token characters only (letters, digits, hyphens).
- Never include spaces, colons, or non-ASCII characters in header names.
- Generate header names from a vetted allow-list.
When it happens
Trigger: Registering a tool with an x-mcp-header value containing spaces, colons, non-ASCII characters, or control characters — e.g. "X Custom", "X-Header:", or "ヘッダー".
Common situations: Including a colon in the header name (the separator belongs only in the serialized line); using spaces or hyphens-with-spaces; copying a localized header label into the annotation; trailing whitespace.
Related errors
- property %q: x-mcp-header must be a non-empty string
- property %q: duplicate x-mcp-header value %q
- schema exceeds %d bytes
- root type must be "object"
- property %q: x-mcp-header can only be applied to primitive t
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/ab24c1d2ed3c7743.
Report an issue: GitHub.