{"record":{"id":"9a41d849fdd86cb0","repo":"PrefectHQ/fastmcp","slug":"host-origin-protection-must-be-true-false-or-au","errorCode":null,"errorMessage":"host_origin_protection must be True, False, or 'auto'.","messagePattern":"host_origin_protection must be True, False, or 'auto'\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/server/http.py","lineNumber":650,"sourceCode":"    else:\n        # No auth required\n        http_methods = [\"POST\", \"DELETE\"] if stateless_http else None\n        server_routes.append(\n            Route(\n                streamable_http_path,\n                endpoint=streamable_http_app,\n                methods=http_methods,\n            )\n        )\n\n    # Add custom routes with lowest precedence\n    if routes:\n        server_routes.extend(routes)\n    server_routes.extend(server._get_additional_http_routes())\n\n    # Add middleware\n    if host_origin_protection not in (True, False, \"auto\"):\n        raise ValueError(\"host_origin_protection must be True, False, or 'auto'.\")\n\n    if host_origin_protection is not False:\n        server_middleware.insert(\n            0,\n            Middleware(\n                HostOriginGuardMiddleware,\n                allowed_hosts=allowed_hosts,\n                allowed_origins=allowed_origins,\n                mode=\"strict\" if host_origin_protection is True else \"auto\",\n            ),\n        )\n    if middleware:\n        server_middleware.extend(middleware)\n\n    # Create a lifespan manager to start and stop the session manager\n    @asynccontextmanager\n    async def lifespan(app: Starlette) -> AsyncGenerator[None, None]:\n        streamable_http_app.session_manager = FastMCPStreamableHTTPSessionManager(","sourceCodeStart":632,"sourceCodeEnd":668,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/server/http.py#L632-L668","documentation":"create_streamable_http_app validates the host_origin_protection flag against the allowed values True, False, and 'auto' (where 'auto' enables DNS-rebinding protection only for non-localhost binds). Any other value raises ValueError before middleware is assembled.","triggerScenarios":"Calling server.create_streamable_http_app(host_origin_protection=...) or http_app(...) with a truthy/falsy non-boolean like a string 'true', 'yes', 1, or None.","commonSituations":"Config-driven deployments where the setting is parsed from YAML/env as a string ('false' is neither True/False/'auto'); typos like 'Auto'; passing CLI string flags without coercion.","solutions":["Coerce config values to bool before passing: host_origin_protection = raw in (True, 'true', '1') or raw == 'auto' and 'auto'.","Pass exactly True, False, or 'auto' (lowercase string) as the argument.","Normalize env/YAML strings: value = {'true': True, 'false': False}.get(str(raw).lower(), 'auto') when raw is a string.","Omit the argument to use the default instead of passing None."],"exampleFix":"// before\napp = server.http_app(host_origin_protection=\"true\")  # ValueError\n// after\nraw = os.getenv(\"HOST_ORIGIN_PROTECTION\", \"auto\")\nhop = {\"true\": True, \"false\": False}.get(raw.lower(), \"auto\")\napp = server.http_app(host_origin_protection=hop)","handlingStrategy":"validation","validationCode":"RAW = os.getenv(\"HOST_ORIGIN_PROTECTION\", \"auto\")\nvalue = {\"true\": True, \"false\": False}.get(str(RAW).lower(), \"auto\")\nassert value in (True, False, \"auto\")","typeGuard":"def is_valid_hop(v) -> bool:\n    return v is True or v is False or v == \"auto\"","tryCatchPattern":"try:\n    app = server.http_app(host_origin_protection=raw)\nexcept ValueError:\n    app = server.http_app(host_origin_protection=\"auto\")","preventionTips":["Coerce string config/env values to bool before passing the flag","Only pass the literal True, False, or 'auto'","Add a config-load unit test covering all three accepted values"],"tags":["configuration","http-app","validation"],"backgroundTag":"invalid-config-value","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}