{"record":{"id":"578c2864a4194fbb","repo":"sipeed/picoclaw","slug":"invalid-trusted-proxy-cidr-q","errorCode":null,"errorMessage":"invalid trusted proxy CIDR %q","messagePattern":"invalid trusted proxy CIDR %q","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"warning","filePath":"web/backend/api/launcher_config.go","lineNumber":92,"sourceCode":"\t\thttp.Error(w, fmt.Sprintf(\"Invalid JSON: %v\", err), http.StatusBadRequest)\n\t\treturn\n\t}\n\n\tcfg, err := h.loadLauncherConfig()\n\tif err != nil {\n\t\thttp.Error(w, fmt.Sprintf(\"Failed to load launcher config: %v\", err), http.StatusInternalServerError)\n\t\treturn\n\t}\n\tcfg.Port = payload.Port\n\tcfg.Public = payload.Public\n\tcfg.AllowedCIDRs = append([]string(nil), payload.AllowedCIDRs...)\n\tif payload.AllowLocalhostBypass != nil {\n\t\tcfg.AllowLocalhostBypass = *payload.AllowLocalhostBypass\n\t}\n\tcfg.TrustedProxyCIDRs = append([]string(nil), payload.TrustedProxyCIDRs...)\n\tcfg.LegacyLauncherToken = \"\"\n\tif err := launcherconfig.Validate(cfg); err != nil {\n\t\thttp.Error(w, err.Error(), http.StatusBadRequest)\n\t\treturn\n\t}\n\n\tif err := launcherconfig.Save(h.launcherConfigPath(), cfg); err != nil {\n\t\thttp.Error(w, fmt.Sprintf(\"Failed to save launcher config: %v\", err), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tw.Header().Set(\"Content-Type\", \"application/json\")\n\tjson.NewEncoder(w).Encode(launcherConfigPayload{\n\t\tPort:                 cfg.Port,\n\t\tPublic:               cfg.Public,\n\t\tAllowedCIDRs:         append([]string(nil), cfg.AllowedCIDRs...),\n\t\tAllowLocalhostBypass: cfg.AllowLocalhostBypass,\n\t\tTrustedProxyCIDRs:    append([]string(nil), cfg.TrustedProxyCIDRs...),\n\t})\n}\n","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/web/backend/api/launcher_config.go#L74-L110","documentation":"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.","triggerScenarios":"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.","commonSituations":"Configuring reverse-proxy trust for the first time and copying the proxy address straight from DNS; load balancer docs that list IPs without prefixes.","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"],"exampleFix":"// before\n{\"trusted_proxy_cidrs\": [\"proxy.internal.lan\"]}\n\n// after - resolved address as /32\n{\"trusted_proxy_cidrs\": [\"10.1.2.3/32\"]}","handlingStrategy":"validation","validationCode":"// Reuse the same CIDR check as allowed_cidrs before sending.\nconst badProxies = payload.trusted_proxy_cidrs.filter(c => !isValidCIDR(c));\nif (badProxies.length) {\n  // common case: user typed the proxy hostname - resolve it first\n  throw new Error('trusted proxies must be CIDRs (e.g. 10.1.2.3/32), got: ' + badProxies.join(', '));\n}","typeGuard":"const isTrustedProxyList = (v: unknown): v is string[] =>\n  Array.isArray(v) && v.every(x => typeof x === 'string' && isValidCIDR(x));","tryCatchPattern":"if (res.status === 400) {\n  const text = await res.text();\n  const m = text.match(/invalid trusted proxy CIDR \"(.*)\"/);\n  if (m) highlightField('trusted_proxy_cidrs', m[1]);\n  throw new Error(text);\n}","preventionTips":["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"],"tags":["validation","cidr","reverse-proxy","launcher","go"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}