cloudflare/cloudflared · error
backend returned invalid network %s
Error message
backend returned invalid network %s
What it means
This error is thrown by CIDR.UnmarshalJSON when the Cloudflare API backend returns a JSON string that net.ParseCIDR parses successfully but yields a nil network — meaning the backend produced a network value that cannot be represented as a CIDR. It indicates the backend response does not conform to the expected IP route schema. The error is a defensive invariant check after successful parsing.
Source
Thrown at cfapi/ip_route.go:60
json, err := json.Marshal(str)
if err != nil {
return nil, errors.Wrap(err, "error serializing CIDR into JSON")
}
return json, nil
}
// UnmarshalJSON parses a JSON string into net.IPNet
func (c *CIDR) UnmarshalJSON(data []byte) error {
var s string
if err := json.Unmarshal(data, &s); err != nil {
return errors.Wrap(err, "error parsing cidr string")
}
_, network, err := net.ParseCIDR(s)
if err != nil {
return errors.Wrap(err, "error parsing invalid network from backend")
}
if network == nil {
return fmt.Errorf("backend returned invalid network %s", s)
}
*c = CIDR(*network)
return nil
}
// NewRoute has all the parameters necessary to add a new route to the table.
type NewRoute struct {
Network net.IPNet
TunnelID uuid.UUID
Comment string
// Optional field. If unset, backend will assume the default vnet for the account.
VNetID *uuid.UUID
}
// MarshalJSON handles fields with non-JSON types (e.g. net.IPNet).
func (r NewRoute) MarshalJSON() ([]byte, error) {
return json.Marshal(&struct {
Network string `json:"network"`View on GitHub (pinned to 2253eeeb25)
Solutions
- Verify the exact JSON value the backend returned for the network field (log the raw response body before unmarshalling).
- Update cloudflared/cfapi types to match the current Cloudflare API schema for IP routes.
- If the backend can return an empty value, pre-filter route entries or add a custom UnmarshalJSON path that skips blank strings.
- Report the malformed backend response to Cloudflare support with the request ID if the API genuinely returned a bad network.
Example fix
// before
type Route struct {
Network cfapi.CIDR `json:"network"`
}
// after
type Route struct {
Network cfapi.CIDR `json:"network"`
}
// guard before decode:
var raw struct{ Network string `json:"network"` }
_ = json.Unmarshal(body, &raw)
if _, _, err := net.ParseCIDR(raw.Network); err != nil || raw.Network == "" { /* skip or handle */ } Defensive patterns
Strategy: validation
Validate before calling
func validCIDR(s string) bool {
if s == "" { return false }
_, n, err := net.ParseCIDR(s)
return err == nil && n != nil
}
if !validCIDR(raw.Network) { /* skip entry or handle before json.Unmarshal into cfapi.CIDR */ } Type guard
func isParsedCIDR(n *net.IPNet) bool { return n != nil } Prevention
- Log raw API responses when unmarshalling backend types
- Pin and test cfapi types against current API fixtures
- Skip entries with empty network strings before decoding
When it happens
Trigger: Unmarshalling a JSON payload (e.g. from the /ip_routes API) into cfapi.CIDR where the string parses via net.ParseCIDR without error yet returns a nil *net.IPNet, which in practice means an empty or malformed value slipped past the parser.
Common situations: Cloudflare API schema changes or bugs returning unexpected route fields; stale SDK types used against a newer/older API; mocked or replayed test fixtures with empty network strings.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/e08a0c069c78e7bb.
Report an issue: GitHub.