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

  1. Set a valid service CIDR in the cluster spec, e.g. `kops set cluster networking.serviceClusterIPRange=100.64.0.0/13`
  2. Fix CIDR syntax — it must include the prefix length (x.x.x.x/nn)
  3. 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

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


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/e2263def1b018ea4. Report an issue: GitHub.