Skip to content

[Bug]: Host header validation breaks reverse proxy setups without explicit override (403 Forbidden: invalid Host header) #898

Description

@zeeid

What happened?

Description

When running mcpproxy behind an nginx reverse proxy (via CloudPanel), requests are rejected with:Forbidden: invalid Host header

This happens even though the proxy correctly forwards the request to mcpproxy's
listen address. It only works if I explicitly override the Host header in nginx
to match mcpproxy's bind address (e.g. 127.0.0.1:8004) instead of passing through
the original public domain.

Environment

  • mcpproxy version: v0.51.0 (also reproduced on v0.52.0-rc.2)
  • Listen address: 127.0.0.1:8004
  • Reverse proxy: nginx (via CloudPanel)
  • A separate instance running v0.49.0 on the same host/port, with a plain
    nginx config (no Host override, no buffering changes), works fine — same
    auth method (?api_key= query param).

Workaround

Forcing the Host header to match the local bind address resolves it:

proxy_set_header Host 127.0.0.1:8004;
proxy_buffering off;
proxy_request_buffering off;

Questions

  1. Is this an intentional DNS-rebinding protection added between v0.49.0 and
    v0.51.0? I couldn't find it documented in the release notes or CHANGELOG.md
    for either version.
  2. If intentional, is there a config option (e.g. trusted_hosts /
    allowed_hosts) to allow specific public domains without having to spoof
    the Host header at the proxy layer? Overriding Host to the loopback address
    feels like a workaround rather than the intended setup for reverse-proxied
    deployments.
  3. If this is documented somewhere, a pointer to the docs page for reverse
    proxy / Host validation config would be appreciated — I couldn't find one
    at docs.mcpproxy.app.

Happy to provide full nginx configs (before/after) and logs if useful.

Expected behavior

Expected Behavior

Requests forwarded through a reverse proxy with the original public domain in
the Host header (e.g. Host: mcp.example.com) should be accepted by mcpproxy,
either:

  • by default (if Host validation isn't intended to block legitimate
    reverse-proxied setups), or
  • after configuring the public domain as a trusted/allowed host via a config
    option (e.g. trusted_hosts in mcp_config.json or an environment
    variable), without needing to override the Host header to the internal
    loopback address (127.0.0.1:8004) at the nginx layer.

Currently, the only way to avoid the 403 Forbidden: invalid Host header
error is to spoof the Host header to match mcpproxy's bind address, which
works but isn't documented anywhere and feels like an unintended workaround
rather than the supported configuration path for reverse-proxied deployments.

Steps to reproduce

Steps to Reproduce

  1. Run mcpproxy with --listen 127.0.0.1:8004
  2. Reverse proxy mcp.example.com127.0.0.1:8004 via nginx with standard
    proxy_set_header Host $host;
  3. Send a request to https://mcp.example.com/mcp?api_key=...
  4. Response: 403 Forbidden: invalid Host header "mcp.example.com"

MCPProxy version

v0.51.0

Operating system

Linux

Relevant logs

Pre-submission checklist

  • I searched existing issues and did not find a duplicate
  • I ran mcpproxy doctor and reviewed the output

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions