{"record":{"id":"d726ca06c44426e3","repo":"kubernetes/kops","slug":"sourcerange-q-is-not-valid-w","errorCode":null,"errorMessage":"sourceRange %q is not valid: %w","messagePattern":"sourceRange %q is not valid: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/gcetasks/firewallrule.go","lineNumber":120,"sourceCode":"\t\tif len(e.SourceRanges) == 0 && len(e.SourceTags) == 0 {\n\t\t\treturn fmt.Errorf(\"either SourceRanges or SourceTags should be specified when Disabled is false\")\n\t\t}\n\t}\n\n\t// Treat it as an error if SourceRanges _and_ SourceTags both set;\n\t// this is interpreted as OR, not AND, which is likely not what was intended.\n\tif len(e.SourceRanges) != 0 && len(e.SourceTags) != 0 {\n\t\treturn fmt.Errorf(\"SourceRanges and SourceTags should not both be specified\")\n\t}\n\n\tname := fi.ValueOf(e.Name)\n\n\t// Make sure we've split the ipv4 / ipv6 addresses.\n\t// A single firewall rule can't mix ipv4 and ipv6 addresses, so we split them into two rules.\n\tfor _, sourceRange := range e.SourceRanges {\n\t\t_, cidr, err := net.ParseCIDR(sourceRange)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"sourceRange %q is not valid: %w\", sourceRange, err)\n\t\t}\n\n\t\tif e.Family == \"\" {\n\t\t\t// This is our own requirement, just for consistency checking.\n\t\t\t// Previous we used the name, but that was confused when the cluster name was ipv6.example.com\n\t\t\treturn fmt.Errorf(\"must set Family when using SourceRanges\")\n\t\t}\n\n\t\tif cidr.IP.To4() != nil {\n\t\t\t// IPv4\n\t\t\tif e.Family != AddressFamilyIPv4 {\n\t\t\t\treturn fmt.Errorf(\"ipv4 ranges should not be in a ipv6-named rule (found %s in %s)\", sourceRange, name)\n\t\t\t}\n\t\t} else {\n\t\t\t// IPv6\n\t\t\tif e.Family != AddressFamilyIPv6 {\n\t\t\t\treturn fmt.Errorf(\"ipv6 ranges should be in a ipv6-named rule (found %s in %s)\", sourceRange, name)\n\t\t\t}","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/gcetasks/firewallrule.go#L102-L138","documentation":"Validation error from FirewallRule.Normalize raised while splitting source ranges into IPv4/IPv6 groups. A value in e.SourceRanges failed CIDR parsing; the %w wraps the underlying net.ParseCIDR-style error naming the malformed range.","triggerScenarios":"A sourceRanges entry like \"10.0.0.1\" (bare IP without prefix) or \"10.0.0.0/33\" fails net.ParseCIDR inside the loop over e.SourceRanges.","commonSituations":"Typing a single IP without /32; typos in prefix length; IPv6 addresses with wrong notation; values generated by broken tooling/templating.","solutions":["Correct the malformed CIDR in the firewall rule spec (e.g. add the prefix length: 10.0.0.0/8 not 10.0.0.0)","Ensure each source range is a valid IPv4 or IPv6 CIDR — lone IPs are not accepted here"],"exampleFix":"// before\nsourceRanges: [\"10.0.0.1\"]\n// after\nsourceRanges: [\"10.0.0.1/32\"]","handlingStrategy":"validation","validationCode":"for _, r := range rule.SourceRanges {\n  if _, _, err := net.ParseCIDR(r); err != nil {\n    return fmt.Errorf(\"sourceRange %q is not valid CIDR: %w\", r, err)\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always include a prefix length (/32 for single IPs)","Run manifest lint/cidr validation pre-apply","Guard templating output with net.ParseCIDR checks"],"tags":["gcp","gce","firewall","cidr","validation"],"backgroundTag":"invalid-cidr-notation","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}