BerriAI/litellm · error · HTTPException

ip_filtering

ip_filtering

Error message

MCP server '{server_id}' is not accessible from your IP address ({_rest_client_ip}). This server is restricted to internal networks only. To make it externally accessible, set 'available_on_public_internet: true' in the server configuration.

What it means

On the REST tool-call route, the requested server exists in the registry but available_on_public_internet is false (the default) and _is_server_accessible_from_ip judges the caller's client IP non-internal, so the proxy refuses with 403 error=ip_filtering. The message embeds the offending client IP and the exact config knob to change.

Source

Thrown at litellm/proxy/_experimental/mcp_server/rest_endpoints.py:467

            )
            allowed_server_ids_set.update(servers)

        allowed_server_ids_set = set(
            global_mcp_server_manager.filter_server_ids_by_ip(list(allowed_server_ids_set), _rest_client_ip)
        )

        canonical_server_id: Final = _resolve_mcp_server_id_for_rest(server_id, allowed_server_ids_set, _rest_client_ip)

        if canonical_server_id not in allowed_server_ids_set:
            _server: Final = global_mcp_server_manager.get_mcp_server_by_id(
                server_id
            ) or global_mcp_server_manager.get_mcp_server_by_name(server_id)
            if (
                _server is not None
                and _rest_client_ip is not None
                and not global_mcp_server_manager._is_server_accessible_from_ip(_server, _rest_client_ip)
            ):
                raise HTTPException(
                    status_code=403,
                    detail={
                        "error": "ip_filtering",
                        "message": (
                            f"MCP server '{server_id}' is not accessible from your IP address "
                            f"({_rest_client_ip}). This server is restricted to internal "
                            "networks only. To make it externally accessible, set "
                            "'available_on_public_internet: true' in the server configuration."
                        ),
                    },
                )
            if _server is None:
                raise HTTPException(
                    status_code=404,
                    detail={
                        "error": "server_not_found",
                        "message": f"MCP server '{server_id}' was not found",
                    },

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. If the server should be internet-reachable, set available_on_public_internet: true on that mcp_servers entry (config.yaml or DB) and reload the proxy.
  2. Otherwise call from an allowed internal network/VPN.
  3. If you believe you are internal: check the reported IP in the message and fix X-Forwarded-For / trusted-proxy forwarding so the real client IP is derived.

Example fix

# before
mcp_servers:
  internal-wiki:
    url: https://wiki.internal
# -> 403 ip_filtering for external callers

# after
mcp_servers:
  internal-wiki:
    url: https://wiki.internal
    available_on_public_internet: true
Defensive patterns

Strategy: validation

Validate before calling

import ipaddress

def client_ip_can_reach_server(client_ip: str | None, server_public: bool) -> bool:
    if server_public:
        return True
    if not client_ip:
        return False
    try:
        return ipaddress.ip_address(client_ip).is_private or ipaddress.ip_address(client_ip).is_loopback
    except ValueError:
        return False

assert client_ip_can_reach_server(my_ip, server_config.get("available_on_public_internet", False))

Try / catch

resp = await client.post(f"{proxy}/mcp/tool-call", json=payload, headers=headers)
if resp.status_code == 403 and resp.json().get("detail", {}).get("error") == "ip_filtering":
    raise NetworkLocationError("call must originate from an internal IP or the server must set available_on_public_internet: true") from None
resp.raise_for_status()

Prevention

When it happens

Trigger: Calling a restricted internal MCP server over the REST facade from a public/egress IP; or the client IP is derived incorrectly because a reverse proxy does not forward X-Forwarded-For (or the proxy's trusted-proxy handling is misconfigured), making even internal callers appear external.

Common situations: Exposing the litellm proxy publicly while leaving default servers internal-only; k8s ingress stripping XFF; on-prem callers behind NAT; security policy requires an explicit opt-in per server before internet exposure.

Related errors


AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18). Data as JSON: /api/errors/8c49da107dc3995b. Report an issue: GitHub.