{"record":{"id":"75e8e23a4c827662","repo":"headroomlabs-ai/headroom","slug":"not-found","errorCode":null,"errorMessage":"Not Found","messagePattern":"Not Found","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"error","filePath":"headroom/proxy/loopback_guard.py","lineNumber":203,"sourceCode":"       who actually reaches the listener from outside ``127.0.0.0/8``\n       / ``::1``.\n    2. The inbound ``Host:`` header must also name loopback. Stops\n       DNS-rebinding attacks where a browser sends requests to the\n       loopback IP but the page origin is ``attacker.com`` — the IP\n       check alone passes, but the ``Host:`` header still reads\n       ``attacker.com`` and we reject the request here.\n\n    Returning 404 (not 403) keeps debug endpoints invisible to\n    external scanners — indistinguishable from \"no such route\".\n    \"\"\"\n    if HTTPException is None:  # pragma: no cover - defensive\n        raise RuntimeError(\"FastAPI is required for the loopback guard\")\n\n    client = getattr(request, \"client\", None)\n    host = getattr(client, \"host\", None) if client is not None else None\n    if not is_loopback_host(host):\n        # No body: minimal FastAPI default, behaves like \"no route\".\n        raise HTTPException(status_code=404)\n\n    headers = getattr(request, \"headers\", None)\n    if headers is None:\n        # Manual ``Request`` stub with no ``headers`` attribute — used\n        # by older unit tests that pre-date this gate. Treat the same\n        # way as the IP-only path did and accept.\n        return\n    try:\n        host_header = headers.get(\"host\")\n    except AttributeError:\n        host_header = None\n    if not is_loopback_host_header(host_header):\n        raise HTTPException(status_code=404)\n\n\ndef require_same_origin(request: Request) -> None:  # type: ignore[valid-type]\n    \"\"\"FastAPI dependency: reject cross-origin browser requests on mutating routes.\n","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/headroomlabs-ai/headroom/blob/322425c43bffde1ed0b64fecf3cf5951565dd82b/headroom/proxy/loopback_guard.py#L185-L221","documentation":"Error \"Not Found\" thrown in headroomlabs-ai/headroom.","triggerScenarios":"Returned by the loopback guard when a request targets a path that is not served, responding 404 Not Found.","commonSituations":"See trigger scenarios.","solutions":["Verify the request path matches a route the proxy actually serves","If you expected a dashboard/loopback route, check it is enabled and you are hitting the right port","Check proxy logs for the registered routes"],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"322425c43bffde1ed0b64fecf3cf5951565dd82b","analyzedAt":"2026-08-15T01:03:05.481Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}