cilium/cilium · error

invalid IP family: %s

Error message

invalid IP family: %s

What it means

GetIPPoolForPod validates the requested address family before consulting pool selectors. If the family argument is neither ipam.IPv6 nor ipam.IPv4 (e.g. zero value or an unknown Family), the manager refuses to proceed because pool matching is family-scoped and an unknown family would produce wrong or empty matches.

Source

Thrown at pkg/ipam/metadata/manager.go:130

			return annotations[annotation.IPAMPoolKey], true
		}
	case ipam.IPv6:
		if annotations[annotation.IPAMIPv6PoolKey] != "" {
			return annotations[annotation.IPAMIPv6PoolKey], true
		} else if annotations[annotation.IPAMPoolKey] != "" {
			return annotations[annotation.IPAMPoolKey], true
		}
	}

	return "", false
}

func (m *manager) GetIPPoolForPod(owner string, family ipam.Family) (pool string, err error) {
	if !m.poolsSynced.Load() {
		return "", ErrManagerPoolsNotSynced
	}
	if family != ipam.IPv6 && family != ipam.IPv4 {
		return "", fmt.Errorf("invalid IP family: %s", family)
	}

	namespace, name, ok := splitK8sPodName(owner)
	if !ok {
		m.logger.Debug(
			"pool selector: IPAM metadata request for invalid pod name, falling back to default pool",
			logfields.Owner, owner,
		)
		return ipam.PoolDefault().String(), nil
	}

	txn := m.db.ReadTxn()

	// Check annotation on pod
	pod, _, found := m.pods.Get(txn, k8sTables.PodByName(namespace, name))
	if !found {
		return "", &ResourceNotFound{Resource: "Pod", Namespace: namespace, Name: name}
	} else if ippool, ok := determinePoolByAnnotations(pod.Annotations, family); ok {

View on GitHub (pinned to ac7b90affa)

Solutions

  1. Pass an explicit ipam.IPv4 or ipam.IPv6 constant to GetIPPoolForPod
  2. Derive the family via ipam.DeriveFamilyFromIP or equivalent on a successfully parsed net.IP
  3. Check caller config: ensure IPv4 or IPv6 is actually enabled so a real family is computed
  4. Add a switch over ipam.Family at the call site to catch unhandled values at compile/review time

Example fix

// before
pool, err := mgr.GetIPPoolForPod(podName, familyFromConfig) // family may be ""
// after
if familyFromConfig != ipam.IPv4 && familyFromConfig != ipam.IPv6 {
    familyFromConfig = ipam.IPv4 // or derive from the pod IP
}
pool, err := mgr.GetIPPoolForPod(podName, familyFromConfig)
Defensive patterns

Strategy: validation

Validate before calling

if family != ipam.IPv4 && family != ipam.IPv6 {
    return fmt.Errorf("caller bug: unsupported family %q", family)
}
pool, err := mgr.GetIPPoolForPod(owner, family)

Type guard

func validFamily(f ipam.Family) bool { return f == ipam.IPv4 || f == ipam.IPv6 }

Prevention

When it happens

Trigger: Calling GetIPPoolForPod(owner, family) with a Family value other than ipam.IPv4 or ipam.IPv6 — typically the zero value of ipam.Family (empty string) or a family derived from unparsed/unvalidated config or an address with no discernible family.

Common situations: A caller derives the family from a pod IP that failed to parse; config where --ipv4/--ipv6 are both disabled so family is never set; new Family constants added upstream but not handled here; unit tests passing an empty family accidentally.

Related errors


AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31). Data as JSON: /api/errors/35cdcab2ab453f87. Report an issue: GitHub.