kubernetes/kops · error
ipv6 ranges should be in a ipv6-named rule (found %s in %s)
Error message
ipv6 ranges should be in a ipv6-named rule (found %s in %s)
What it means
Normalize() on a GCE FirewallRule validates that every source range's IP family matches the rule name's ipv4/ipv6 designation. This error means a CIDR block parsed as IPv6 was placed in a rule whose name does not carry the ipv6 suffix/designation. kOps derives firewall rule names from cluster naming conventions, so the name and the range list must agree.
Source
Thrown at upup/pkg/fi/cloudup/gcetasks/firewallrule.go:137
if err != nil {
return fmt.Errorf("sourceRange %q is not valid: %w", sourceRange, err)
}
if e.Family == "" {
// This is our own requirement, just for consistency checking.
// Previous we used the name, but that was confused when the cluster name was ipv6.example.com
return fmt.Errorf("must set Family when using SourceRanges")
}
if cidr.IP.To4() != nil {
// IPv4
if e.Family != AddressFamilyIPv4 {
return fmt.Errorf("ipv4 ranges should not be in a ipv6-named rule (found %s in %s)", sourceRange, name)
}
} else {
// IPv6
if e.Family != AddressFamilyIPv6 {
return fmt.Errorf("ipv6 ranges should be in a ipv6-named rule (found %s in %s)", sourceRange, name)
}
}
}
return nil
}
func (_ *FirewallRule) CheckChanges(a, e, changes *FirewallRule) error {
if e.Network == nil {
return fi.RequiredField("Network")
}
return nil
}
func parseFirewallAllowed(rule string) (*compute.FirewallAllowed, error) {
o := &compute.FirewallAllowed{}
tokens := strings.Split(rule, ":")View on GitHub (pinned to 4c8573c808)
Solutions
- Rename the firewall rule so it carries the ipv6 designation (include 'ipv6' in the rule name per kOps GCE naming convention).
- Change the source range to an IPv4 CIDR if the rule is intended to be IPv4.
- If both families are needed, split into two rules: one ipv4-named with IPv4 ranges, one ipv6-named with IPv6 ranges.
Example fix
// before name: "https-to-nodes" sourceRanges: ["fd00::/8"] // after name: "https-to-nodes-ipv6" sourceRanges: ["fd00::/8"]
Defensive patterns
Strategy: validation
Validate before calling
func validateFamilyMatchesName(ruleName string, sourceRanges []string) error {
for _, r := range sourceRanges {
_, ipnet, err := net.ParseCIDR(r)
if err != nil { return fmt.Errorf("bad CIDR %q: %w", r, err) }
isV6 := ipnet.IP.To16() != nil && ipnet.IP.To4() == nil
nameIsV6 := strings.Contains(ruleName, "ipv6")
if isV6 != nameIsV6 {
return fmt.Errorf("range %q (%s) does not match rule name %q", r, family(isV6), ruleName)
}
}
return nil
} Type guard
func isIPv6CIDR(r string) bool {
_, ipnet, err := net.ParseCIDR(r)
return err == nil && ipnet.IP.To4() == nil
} Prevention
- Always include 'ipv4' or 'ipv6' in GCE firewall rule names to match kOps conventions.
- Split dual-stack rules into separate ipv4/ipv6 rules at spec authoring time.
- Add a lint step on cluster manifests that checks CIDR family vs rule name.
When it happens
Trigger: A FirewallRule task in the cluster spec has a source range like 'fd00::/8' (AddressFamilyIPv6) but the rule name lacks the ipv6 marker; Normalize() is invoked during task validation before rendering to GCE.
Common situations: Hand-edited cluster specs adding IPv6 source ranges to legacy IPv4-named rules; upgrading a cluster to dual-stack without renaming rules; templated manifests where ranges were swapped but names were not.
Related errors
- must set Family when using SourceRanges
- ipv4 ranges should not be in a ipv6-named rule (found %s in
- either SourceRanges or SourceTags should be specified when D
- SourceRanges and SourceTags should not both be specified
- sourceRange %q is not valid: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/8d7e3e7ff18c902e.
Report an issue: GitHub.