headroomlabs-ai/headroom · error · ValueError
Invalid {TRUSTED_DASHBOARD_CLIENT_CIDRS_ENV} entry: {exc}
Error message
Invalid {TRUSTED_DASHBOARD_CLIENT_CIDRS_ENV} entry: {exc} What it means
load_trusted_dashboard_client_cidrs() parses HEADROOM_PROXY_TRUSTED_DASHBOARD_CLIENT_CIDRS (a comma-separated CIDR list identifying gateways whose X-Forwarded-For may be trusted) via ipaddress.ip_network(). Any entry the ip module rejects — bad mask, host bits set without strict=False, malformed address — is re-raised as this ValueError with the underlying ipaddress message chained. The check runs at request-handling/config load time, so a bad list can break trust resolution.
Source
Thrown at headroom/proxy/forwarded_headers.py:130
the process environment. A malformed entry raises
:class:`ValueError` — let it propagate so the failure is loud at
startup instead of silently disabling the gate.
"""
if raw is None:
raw = os.environ.get(TRUSTED_GATEWAY_CIDRS_ENV, "")
return _parse_cidr_list(raw)
def load_trusted_dashboard_client_cidrs(
raw: str | None = None,
) -> tuple[ipaddress.IPv4Network | ipaddress.IPv6Network, ...]:
"""Parse the Dashboard client CIDR allow-list from its environment variable."""
if raw is None:
raw = os.environ.get(TRUSTED_DASHBOARD_CLIENT_CIDRS_ENV, "")
try:
return _parse_cidr_list(raw)
except ValueError as exc:
raise ValueError(f"Invalid {TRUSTED_DASHBOARD_CLIENT_CIDRS_ENV} entry: {exc}") from exc
def _normalize_ip(
host: str,
) -> ipaddress.IPv4Address | ipaddress.IPv6Address | None:
"""Parse ``host`` into an IPv4/IPv6 address, unmapping ``::ffff:*``.
IPv4-mapped IPv6 addresses (``::ffff:10.0.0.1``) — emitted by Linux
dual-stack sockets — are normalized to their underlying IPv4 form
so a CIDR allow-list of ``10.0.0.0/8`` matches them naturally.
Returns ``None`` on malformed input; callers treat that as "not a
trusted gateway".
"""
return normalize_ip(host)
def _peer_host(request: Any) -> str | None:
"""Pull ``request.client.host`` defensively (TestClient may omit)."""View on GitHub (pinned to 322425c43b)
Solutions
- Use well-formed CIDR networks: 10.0.0.0/8, 192.168.0.0/16, 2001:db8::/32; write single hosts as a.b.c.d/32.
- Validate the list before deploying: python -c "import ipaddress,sys; [ipaddress.ip_network(s.strip()) for s in sys.argv[1].split(',') if s.strip()]" "$VALUE".
- Remove trailing commas and stray empty entries from comma-separated lists.
Example fix
# before export HEADROOM_PROXY_TRUSTED_DASHBOARD_CLIENT_CIDRS="10.0.0.1/8" # after export HEADROOM_PROXY_TRUSTED_DASHBOARD_CLIENT_CIDRS="10.0.0.0/8"
Defensive patterns
Strategy: validation
Validate before calling
import ipaddress
def cidr_list_ok(raw: str) -> str | None:
try:
nets = [ipaddress.ip_network(s.strip()) for s in raw.split(",") if s.strip()]
return None
except ValueError as exc:
return str(exc) Try / catch
try:
cidrs = load_trusted_dashboard_client_cidrs(raw)
except ValueError as exc:
raise ConfigError(f"fix {TRUSTED_DASHBOARD_CLIENT_CIDRS_ENV}: {exc}") from exc Prevention
- Always write networks, not hosts: 10.0.0.0/8, and /32 for a single address.
- Add a pre-deploy check that parses every CIDR env var with ipaddress.ip_network.
- Avoid trailing commas/whitespace-only entries in comma-separated lists.
When it happens
Trigger: Setting HEADROOM_PROXY_TRUSTED_DASHBOARD_CLIENT_CIDRS to a value containing an invalid CIDR: '10.0.0.1/8' (host bits set — strict networks required), '10.0.0.0/33' (bad mask), 'not-an-ip/8', '10.0.0.0/8,,' (empty segment from a trailing comma may or may not be filtered — invalid segments are rejected).
Common situations: Entering a single host IP where a network is expected (10.0.0.1 instead of 10.0.0.1/32); IPv6 zone identifiers or compressed forms that ipaddress rejects; copy-pasting a list with a trailing comma or whitespace-only entry; typos in the mask.
Related errors
- bedrock_eventstream_parse_failed
- Unknown provider: {self.llm_config.provider}
- HEADROOM_LEARN_CLI={cli_override!r} is not a supported CLI.
- max_size must be at least 1, got {max_size}
- save_path must be provided when auto_save is True
AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15).
Data as JSON: /api/errors/b49c55ba36d3fdba.
Report an issue: GitHub.