{"record":{"id":"6c1a6e434c22d2b1","repo":"kubernetes/kubernetes","slug":"servicecidr-and-secondaryservicecidr-are-not-duals-6c1a6e","errorCode":null,"errorMessage":"serviceCIDR and secondaryServiceCIDR are not dualstack (from different IPfamiles)","messagePattern":"serviceCIDR and secondaryServiceCIDR are not dualstack \\(from different IPfamiles\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"cmd/kube-controller-manager/app/core.go","lineNumber":128,"sourceCode":"\t\t}\n\t}\n\n\tif len(strings.TrimSpace(controllerContext.ComponentConfig.NodeIPAMController.SecondaryServiceCIDR)) != 0 {\n\t\t_, secondaryServiceCIDR, err = netutils.ParseCIDRSloppy(controllerContext.ComponentConfig.NodeIPAMController.SecondaryServiceCIDR)\n\t\tif err != nil {\n\t\t\tlogger.Info(\"Warning: unsuccessful parsing of service CIDR\", \"CIDR\", controllerContext.ComponentConfig.NodeIPAMController.SecondaryServiceCIDR, \"err\", err)\n\t\t}\n\t}\n\n\t// the following checks are triggered if both serviceCIDR and secondaryServiceCIDR are provided\n\tif serviceCIDR != nil && secondaryServiceCIDR != nil {\n\t\t// should be dual stack (from different IPFamilies)\n\t\tdualstackServiceCIDR, err := netutils.IsDualStackCIDRs([]*net.IPNet{serviceCIDR, secondaryServiceCIDR})\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to perform dualstack check on serviceCIDR and secondaryServiceCIDR error: %w\", err)\n\t\t}\n\t\tif !dualstackServiceCIDR {\n\t\t\treturn nil, fmt.Errorf(\"serviceCIDR and secondaryServiceCIDR are not dualstack (from different IPfamiles)\")\n\t\t}\n\t}\n\n\t// only --node-cidr-mask-size-ipv4 and --node-cidr-mask-size-ipv6 supported with dual stack clusters.\n\t// --node-cidr-mask-size flag is incompatible with dual stack clusters.\n\tnodeCIDRMaskSizes, err := setNodeCIDRMaskSizes(controllerContext.ComponentConfig.NodeIPAMController, clusterCIDRs)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tclient, err := controllerContext.NewClient(\"node-controller\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tnodeIpamController, err := nodeipamcontroller.NewNodeIpamController(\n\t\tctx,\n\t\tcontrollerContext.InformerFactory.Core().V1().Nodes(),","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/kubernetes/kubernetes/blob/b882c60b4023bdf09264c2d5d30a2cadebc240fb/cmd/kube-controller-manager/app/core.go#L110-L146","documentation":"Fires when both ServiceCIDR and SecondaryServiceCIDR are provided and parse cleanly, netutils.IsDualStackCIDRs returns no error, but the boolean result is false — meaning both CIDRs belong to the same IP family (both IPv4 or both IPv6). KCM requires the secondary range to be the opposite family so services can be dual-stack.","triggerScenarios":"Operator sets --service-cluster-ip-range and --secondary-service-cluster-ip-range to two IPv4 CIDRs (or two IPv6 CIDRs) intending to widen the address space rather than enable dual-stack. The IsDualStackCIDRs check at core.go:127 returns false and KCM refuses to start.","commonSituations":"Adding a second IPv4 service range to avoid exhaustion without realizing the secondary flag is reserved for the other family; migrating to dual-stack by copying the primary CIDR and editing only the prefix; docs/templates that show two ranges of the same family.","solutions":["Make the secondary CIDR the opposite family of the primary (IPv6 if primary is IPv4, vice versa)","If dual-stack is not the goal, remove --secondary-service-cluster-ip-range entirely","Validate with: python3 -c \"import ipaddress; print(ipaddress.ip_network('fd00::/112').version)\" for each range"],"exampleFix":"# before\n--service-cluster-ip-range=10.96.0.0/12\n--secondary-service-cluster-ip-range=10.97.0.0/16   # both IPv4 -> fails\n# after\n--service-cluster-ip-range=10.96.0.0/12\n--secondary-service-cluster-ip-range=fd00:1234::/112","handlingStrategy":"validation","validationCode":"func assertDualStackFamilies(primary, secondary string) error {\n    _, p, _ := net.ParseCIDR(primary)\n    _, s, _ := net.ParseCIDR(secondary)\n    if p == nil || s == nil { return errors.New(\"invalid CIDR\") }\n    if (p.IP.To4() == nil) == (s.IP.To4() == nil) {\n        return errors.New(\"primary and secondary service CIDRs share an IP family; make one IPv4 and one IPv6\")\n    }\n    return nil\n}","typeGuard":"null","tryCatchPattern":"null","preventionTips":["If you only need one family, omit the secondary flag","CI: assert that exactly one of the two service CIDRs is IPv6","Generate CIDRs from a single dual-stack allocation rather than two manual strings"],"tags":["kubernetes","kube-controller-manager","networking","dualstack","service-cidr","startup","configuration"],"analyzedSha":"b882c60b4023bdf09264c2d5d30a2cadebc240fb","analyzedAt":"2026-08-07T04:07:48.144Z","schemaVersion":2},"datasetVersion":"2026-08-07T07:17:06.508Z"}