kubernetes/kops · error

unexpected IP address type for ServiceClusterIPRange: %s

Error message

unexpected IP address type for ServiceClusterIPRange: %s

What it means

WellKnownServiceIP supports deriving the well-known IP for IPv4 and IPv6 service CIDRs. If the parsed CIDR's IP is neither a 4-byte nor a 16-byte address (or the computed IP bytes cannot be represented), the function reaches its terminal return and errors that the IP address type is unexpected.

Source

Thrown at pkg/model/components/context.go:133

		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))
		serviceIPBytes := serviceIPInt.Bytes()
		for i := range serviceIPBytes {
			serviceIP[len(serviceIP)-len(serviceIPBytes)+i] = serviceIPBytes[i]
		}
		return serviceIP, nil
	}

	return nil, fmt.Errorf("unexpected IP address type for ServiceClusterIPRange: %s", networkingSpec.ServiceClusterIPRange)
}

// Image returns the docker image name for the specified component
func Image(component string, clusterSpec *kops.ClusterSpec, assetsBuilder *assets.AssetBuilder) (string, error) {
	if assetsBuilder == nil {
		return "", fmt.Errorf("unable to parse assets as assetBuilder is not defined")
	}

	kubernetesVersion, err := kopsmodel.ParseKubernetesVersion(clusterSpec.KubernetesVersion)
	if err != nil {
		return "", err
	}

	imageName := component

	if !kubernetesVersion.IsBaseURL() {
		image := "registry.k8s.io/" + imageName + ":" + "v" + kubernetesVersion.String()

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Use a standard IPv4 (e.g. 100.64.0.0/13) or IPv6 (e.g. fd00:5:64::/108) service CIDR
  2. Inspect cluster.spec.networking.serviceClusterIPRange for stray characters or dual-stack concatenation
  3. Regenerate the manifest with `kops create cluster` defaults instead of hand-editing the field

Example fix

# before
serviceClusterIPRange: 100.64.0.0/13,fd00:5:64::/108
# after (set families separately for dual-stack)
serviceClusterIPRange: 100.64.0.0/13
Defensive patterns

Strategy: validation

Validate before calling

func isSupportedServiceCIDR(s string) bool {
	_, cidr, err := net.ParseCIDR(s)
	if err != nil { return false }
	return cidr.IP.To4() != nil || len(cidr.IP) == net.IPv6len
}

Type guard

func isIPv4OrIPv6CIDR(s string) bool {
	_, cidr, err := net.ParseCIDR(s)
	return err == nil && (cidr.IP.To4() != nil || len(cidr.IP) == net.IPv6len)
}

Try / catch

ip, err := WellKnownServiceIP(networkingSpec, id)
if err != nil {
	if strings.Contains(err.Error(), "unexpected IP address type") {
		// replace CIDR with standard IPv4/IPv6 and retry
	}
	return err
}

Prevention

When it happens

Trigger: ServiceClusterIPRange parses as a CIDR but its base address is not a standard IPv4/IPv6 length — e.g. a 4-in-6 mapped address handling edge case, or an unusually formed CIDR string accepted by ParseCIDR but unsupported downstream.

Common situations: Experimental CIDR values in custom manifests; dual-stack strings accidentally combined (e.g. containing both families); scripts generating CIDRs from non-IP data.

Related errors


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