{"record":{"id":"058905247be5cbf7","repo":"PrefectHQ/fastmcp","slug":"excluded-headers-must-be-lowercase","errorCode":null,"errorMessage":"Excluded headers must be lowercase","messagePattern":"Excluded headers must be lowercase","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"warning","filePath":"fastmcp_slim/fastmcp/server/dependencies.py","lineNumber":585,"sourceCode":"            \"upgrade\",\n            \"te\",\n            \"keep-alive\",\n            \"expect\",\n            \"accept\",\n            \"authorization\",\n            \"cookie\",\n            # Proxy-related headers\n            \"proxy-authenticate\",\n            \"proxy-authorization\",\n            \"proxy-connection\",\n            # MCP-related headers\n            \"mcp-session-id\",\n        }\n        if include:\n            exclude_headers -= {h.lower() for h in include}\n        # Sanity check: all entries must already be lowercase\n        if not all(h.lower() == h for h in exclude_headers):\n            raise ValueError(\"Excluded headers must be lowercase\")\n    headers: dict[str, str] = {}\n\n    try:\n        source: Any = get_http_request().headers.items()\n    except RuntimeError:\n        # No live request: inside a background-task worker, fall back to the\n        # headers the task carried from its originating request (set by the\n        # tasks extension from the snapshot). Empty elsewhere.\n        task_headers = _background_task_headers.get()\n        if task_headers is None:\n            return {}\n        source = task_headers.items()\n\n    for name, value in source:\n        lower_name = name.lower()\n        if lower_name not in exclude_headers:\n            headers[lower_name] = str(value)\n    return headers","sourceCodeStart":567,"sourceCodeEnd":603,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/server/dependencies.py#L567-L603","documentation":"get_http_headers(include, ...) builds a default set of lowercase excluded header names; when a custom include set is provided, FastMCP sanity-checks that every exclusion entry is already lowercase before doing case-sensitive set math. This ValueError is thrown for non-lowercase exclude entries, preventing subtle filtering bugs from HTTP header case-insensitivity.","triggerScenarios":"Calling get_http_headers() while the computed exclusion set contains an entry with uppercase characters — i.e. the include parameter or an internal default contributed a mixed-case header name (e.g. 'Authorization').","commonSituations":"Passing include={'Authorization'} or similarly cased names to get_http_headers; copy-pasting HTTP header names in their canonical Capitalized form.","solutions":["Pass header names in include/exclude entirely lowercase (e.g. 'authorization', not 'Authorization').","Normalize with name.lower() before calling get_http_headers.","HTTP headers are matched case-insensitively downstream, so lowercasing loses nothing."],"exampleFix":"// before\nget_http_headers(include={\"Authorization\"})\n// after\nget_http_headers(include={\"authorization\"})","handlingStrategy":"validation","validationCode":"names = {\"Authorization\"}\nassert all(h == h.lower() for h in names), \"header names must be lowercase\"\nget_http_headers(include=names)","typeGuard":"def all_lowercase(names: set[str]) -> bool:\n    return all(n == n.lower() for n in names)","tryCatchPattern":"try:\n    headers = get_http_headers(include=my_headers)\nexcept ValueError as e:\n    if \"Excluded headers must be lowercase\" in str(e):\n        headers = get_http_headers(include={h.lower() for h in my_headers})\n    else:\n        raise","preventionTips":["Always lowercase header names before passing them in","Remember HTTP headers are case-insensitive","Add a lint/test asserting lowercase header constants"],"tags":["http","headers","validation"],"backgroundTag":"header-name-casing","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}