kubernetes/kops · error
error parsing ServiceClusterIPRange %q: %v
Error message
error parsing ServiceClusterIPRange %q: %v
What it means
WellKnownServiceIP computes the Nth well-known service IP (DNS, etc.) from cluster.spec.networking.serviceClusterIPRange using net.ParseCIDR. If that field is missing or not a valid CIDR, the function cannot derive the IP and fails with this wrapped parse error.
Source
Thrown at pkg/model/components/context.go:107
func (c *OptionsContext) IsKubernetesGTE(version string) bool {
return util.IsKubernetesGTE(version, c.KubernetesVersion)
}
// Deprecated: prefer using NodeKubernetesVersion() and ControlPlaneKubernetesVersion()
func (c *OptionsContext) IsKubernetesLT(version string) bool {
return !c.IsKubernetesGTE(version)
}
// UsesCNI returns true if the networking provider is a CNI plugin
func UsesCNI(networking *kops.NetworkingSpec) bool {
// Kubenet and CNI are the only kubelet networking plugins right now.
return !networking.UsesKubenet()
}
func WellKnownServiceIP(networkingSpec *kops.NetworkingSpec, id int) (net.IP, error) {
_, cidr, err := net.ParseCIDR(networkingSpec.ServiceClusterIPRange)
if err != nil {
return nil, fmt.Errorf("error parsing ServiceClusterIPRange %q: %v", networkingSpec.ServiceClusterIPRange, err)
}
ip4 := cidr.IP.To4()
if ip4 != nil {
n := binary.BigEndian.Uint32(ip4)
n += uint32(id)
serviceIP := make(net.IP, len(ip4))
binary.BigEndian.PutUint32(serviceIP, n)
return serviceIP, nil
}
ip6 := cidr.IP.To16()
if ip6 != nil {
baseIPInt := big.NewInt(0)
baseIPInt.SetBytes(ip6)
serviceIPInt := big.NewInt(0)
serviceIPInt.Add(big.NewInt(int64(id)), baseIPInt)
serviceIP := make(net.IP, len(ip6))View on GitHub (pinned to 4c8573c808)
Solutions
- Set a valid service CIDR in the cluster spec, e.g. `kops set cluster networking.serviceClusterIPRange=100.64.0.0/13`
- Fix CIDR syntax — it must include the prefix length (x.x.x.x/nn)
- Run `kops validate cluster` / `kops get cluster -oyaml` to inspect the current value before editing
Example fix
# before networking: serviceClusterIPRange: 100.64.0.0 # after networking: serviceClusterIPRange: 100.64.0.0/13
Defensive patterns
Strategy: validation
Validate before calling
if networkingSpec.ServiceClusterIPRange == "" {
return fmt.Errorf("serviceClusterIPRange must be set (e.g. 100.64.0.0/13)")
}
if _, _, err := net.ParseCIDR(networkingSpec.ServiceClusterIPRange); err != nil {
return fmt.Errorf("serviceClusterIPRange %q is not a valid CIDR", networkingSpec.ServiceClusterIPRange)
} Type guard
func isValidCIDR(s string) bool { _, _, err := net.ParseCIDR(s); return err == nil } Try / catch
ip, err := WellKnownServiceIP(networkingSpec, id)
if err != nil {
if strings.Contains(err.Error(), "error parsing ServiceClusterIPRange") {
// fix spec.networking.serviceClusterIPRange before retry
}
return err
} Prevention
- Include the prefix length in all CIDR fields (/13, /108)
- Use `kops create cluster` defaults instead of hand-writing service CIDRs
- Validate specs with net.ParseCIDR in tooling before applying manifests
When it happens
Trigger: Calling WellKnownServiceIP (directly or via BuildOptions/writeServerCertificate/configureKubelet) when ServiceClusterIPRange is empty ('') or malformed (e.g. '10.0.0.1' without a mask, '100.64.0.0/xx').
Common situations: Hand-written cluster manifests without the service CIDR; typos in the CIDR; clusters created by older tooling where the field defaulted differently; code paths that call WellKnownServiceIP on specs not yet validated.
Related errors
- unexpected IP address type for ServiceClusterIPRange: %s
- unable to parse Non Masquerade CIDR
- unable to get first ip address in Non Masquerade CIDR
- overflowed CIDR while incrementing IP
- Invalid NetworkCIDR: %q
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/e2263def1b018ea4.
Report an issue: GitHub.