{"record":{"id":"d33df7903a0d6ff2","repo":"slackhq/nebula","slug":"entry-v-route-in-tun-routes-failed-to-parse-v","errorCode":null,"errorMessage":"entry %v.route in tun.routes failed to parse: %v","messagePattern":"entry (.+?)\\.route in tun\\.routes failed to parse: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"overlay/route.go","lineNumber":123,"sourceCode":"\t\t}\n\n\t\tif mtu < 500 {\n\t\t\treturn nil, fmt.Errorf(\"entry %v.mtu in tun.routes is below 500: %v\", i+1, mtu)\n\t\t}\n\n\t\trRoute, ok := m[\"route\"]\n\t\tif !ok {\n\t\t\treturn nil, fmt.Errorf(\"entry %v.route in tun.routes is not present\", i+1)\n\t\t}\n\n\t\tr := Route{\n\t\t\tInstall: true,\n\t\t\tMTU:     mtu,\n\t\t}\n\n\t\tr.Cidr, err = netip.ParsePrefix(fmt.Sprintf(\"%v\", rRoute))\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"entry %v.route in tun.routes failed to parse: %v\", i+1, err)\n\t\t}\n\n\t\tfound := false\n\t\tfor _, network := range networks {\n\t\t\tif network.Contains(r.Cidr.Addr()) && r.Cidr.Bits() >= network.Bits() {\n\t\t\t\tfound = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tif !found {\n\t\t\treturn nil, fmt.Errorf(\n\t\t\t\t\"entry %v.route in tun.routes is not contained within the configured vpn networks; route: %v, networks: %v\",\n\t\t\t\ti+1,\n\t\t\t\tr.Cidr.String(),\n\t\t\t\tnetworks,\n\t\t\t)\n\t\t}","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/overlay/route.go#L105-L141","documentation":"The route value of a tun.routes entry could not be parsed as a CIDR prefix. parseRoutes formats the value with %v and calls netip.ParsePrefix; any parse failure (bad format, missing prefix length, invalid IP, wrong type like a nested map) is wrapped in this error.","triggerScenarios":"getAllRoutesFromConfig sees route values like 10.0.0.1 (no /bits), 10.0.0.0/33, hostname strings, or non-string values (lists/maps) interpolated by %v.","commonSituations":"Using bare host IPs without a prefix length; typos in octets or bits; pasting hostnames instead of CIDRs; YAML types like dates (e.g. 10.0.0.0/08 parsing oddly) or quoted values with whitespace.","solutions":["Provide a valid CIDR prefix such as 10.0.0.0/24 (IP + /prefix-length)","Validate the CIDR with netip.ParsePrefix in a scratch script or an online CIDR checker before committing","Remove whitespace/quotes issues around the value","The inner %v contains the exact netip error — fix the address component it names"],"exampleFix":"// before\n- mtu: 1300\n  route: 10.0.0.1\n// after\n- mtu: 1300\n  route: 10.0.0.0/24","handlingStrategy":"validation","validationCode":"routeStr := fmt.Sprintf(\"%v\", m[\"route\"])\nif _, err := netip.ParsePrefix(routeStr); err != nil {\n    return fmt.Errorf(\"tun.routes route %q is not a valid CIDR: %v\", routeStr, err)\n}","typeGuard":"func isValidCIDR(v any) bool {\n    _, err := netip.ParsePrefix(fmt.Sprintf(\"%v\", v))\n    return err == nil\n}","tryCatchPattern":null,"preventionTips":["Always include a prefix length: 10.0.0.0/24, not 10.0.0.1","Validate CIDRs with netip.ParsePrefix or a linter before deploying","Avoid hostnames and whitespace in route values","Check prefix-length bounds (0-32 for IPv4, 0-128 for IPv6)"],"tags":["config","validation","cidr"],"backgroundTag":"invalid-cidr-prefix","analyzedSha":"dd8f660c0ac37903ec4080ca4d3c861ba9342ceb","analyzedAt":"2026-09-03T11:13:55.444Z","contentChangedAt":"2026-09-03T11:13:55.444Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}