sipeed/picoclaw · warning
invalid trusted proxy CIDR %q
Error message
invalid trusted proxy CIDR %q
What it means
Validation error (400) from PUT /api/system/launcher-config: a trusted_proxy_cidrs entry failed net.ParseCIDR (launcherconfig/config.go:60-64). Same format rules as allowed_cidrs: full CIDR with prefix required. trusted_proxy_cidrs governs which proxies are trusted for X-Forwarded-For handling, so a typical mistake is entering the proxy's hostname or a bare IP instead of its network in CIDR form.
Source
Thrown at web/backend/api/launcher_config.go:92
http.Error(w, fmt.Sprintf("Invalid JSON: %v", err), http.StatusBadRequest)
return
}
cfg, err := h.loadLauncherConfig()
if err != nil {
http.Error(w, fmt.Sprintf("Failed to load launcher config: %v", err), http.StatusInternalServerError)
return
}
cfg.Port = payload.Port
cfg.Public = payload.Public
cfg.AllowedCIDRs = append([]string(nil), payload.AllowedCIDRs...)
if payload.AllowLocalhostBypass != nil {
cfg.AllowLocalhostBypass = *payload.AllowLocalhostBypass
}
cfg.TrustedProxyCIDRs = append([]string(nil), payload.TrustedProxyCIDRs...)
cfg.LegacyLauncherToken = ""
if err := launcherconfig.Validate(cfg); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
if err := launcherconfig.Save(h.launcherConfigPath(), cfg); err != nil {
http.Error(w, fmt.Sprintf("Failed to save launcher config: %v", err), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(launcherConfigPayload{
Port: cfg.Port,
Public: cfg.Public,
AllowedCIDRs: append([]string(nil), cfg.AllowedCIDRs...),
AllowLocalhostBypass: cfg.AllowLocalhostBypass,
TrustedProxyCIDRs: append([]string(nil), cfg.TrustedProxyCIDRs...),
})
}
View on GitHub (pinned to 49183d7e8d)
Solutions
- Express each trusted proxy as CIDR: "10.1.2.3/32" for one host, "10.0.0.0/8" for a range
- Resolve hostnames to addresses first - the validator only accepts numeric CIDRs
- Trim entries client-side; the error message quotes the exact bad value
Example fix
// before
{"trusted_proxy_cidrs": ["proxy.internal.lan"]}
// after - resolved address as /32
{"trusted_proxy_cidrs": ["10.1.2.3/32"]} Defensive patterns
Strategy: validation
Validate before calling
// Reuse the same CIDR check as allowed_cidrs before sending.
const badProxies = payload.trusted_proxy_cidrs.filter(c => !isValidCIDR(c));
if (badProxies.length) {
// common case: user typed the proxy hostname - resolve it first
throw new Error('trusted proxies must be CIDRs (e.g. 10.1.2.3/32), got: ' + badProxies.join(', '));
} Type guard
const isTrustedProxyList = (v: unknown): v is string[] => Array.isArray(v) && v.every(x => typeof x === 'string' && isValidCIDR(x));
Try / catch
if (res.status === 400) {
const text = await res.text();
const m = text.match(/invalid trusted proxy CIDR "(.*)"/);
if (m) highlightField('trusted_proxy_cidrs', m[1]);
throw new Error(text);
} Prevention
- Resolve proxy hostnames to addresses and append /32 before saving
- Copy CIDR values straight from your LB/proxy documentation
- Remember trusted_proxy_cidrs only affects X-Forwarded-For trust - an empty list is valid and safest
When it happens
Trigger: Sending "proxy.internal.lan" (hostname) or "10.1.2.3" (bare IP) instead of "10.1.2.3/32"; IPv6 without a prefix; whitespace-contaminated entries validated before Save's NormalizeCIDRs runs.
Common situations: Configuring reverse-proxy trust for the first time and copying the proxy address straight from DNS; load balancer docs that list IPs without prefixes.
Related errors
- invalid CIDR %q
- Failed to load launcher config: %v
- Invalid JSON: %v
- port %d is out of range (1-65535)
- no models available
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/578c2864a4194fbb.
Report an issue: GitHub.