kubernetes/kops · error

cannot mix publicIP values in private or IPv6-capable subnet

Error message

cannot mix publicIP values in private or IPv6-capable subnets

What it means

The same per-zone consistency check in the AWS network builder also requires every NAT-routing subnet in a zone to share the same `publicIP` value (an explicitly requested Elastic IP allocation for the zone's NAT gateway). If subnets in one zone declare different `publicIP` values, the builder cannot decide which EIP to associate and fails. Raised at model-build time during `kops update cluster`.

Source

Thrown at pkg/model/awsmodel/network.go:435

		allUnmanaged := true
		for _, subnetSpec := range info.NATSubnets {
			if !isUnmanaged(subnetSpec) {
				allUnmanaged = false
			}
		}
		if allUnmanaged {
			klog.V(4).Infof("skipping network configuration in zone %s - all subnets unmanaged", zone)
			continue
		}

		// Verify we don't have mixed values for egress/publicIP - the code doesn't handle it
		for _, subnet := range info.NATSubnets {
			if subnet.Egress != egress {
				return fmt.Errorf("cannot mix egress values in private or IPv6-capable subnets")
			}
			if subnet.PublicIP != publicIP {
				return fmt.Errorf("cannot mix publicIP values in private or IPv6-capable subnets")
			}
		}

		var ngw *awstasks.NatGateway
		var tgwID *string
		var in *awstasks.Instance
		if egress != "" {
			if strings.HasPrefix(egress, "nat-") {

				ngw = &awstasks.NatGateway{
					Name:                 new(zone + "." + b.ClusterName()),
					Lifecycle:            b.Lifecycle,
					Subnet:               egressSubnet,
					ID:                   new(egress),
					AssociatedRouteTable: egressRouteTable,
					// If we're here, it means this NatGateway was specified, so we are Shared
					Shared: new(true),
					Tags:   b.CloudTags(zone+"."+b.ClusterName(), true),

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Make `publicIP` identical (all set to the same EIP, or all empty) for every private/IPv6 subnet in the affected zone.
  2. To reuse one EIP per zone, set it on every subnet spec in that zone, not just the first.
  3. Apply via `kops replace -f cluster.yaml` or `kops edit cluster`, then re-run `kops update cluster`.
  4. If you need distinct EIPs per subnet, split the subnets across zones — the check is per-zone.

Example fix

# before
- name: us-east-1a-private
  type: Private
  zone: us-east-1a
  publicIP: eipalloc-0aaa
- name: us-east-1a-private2
  type: Private
  zone: us-east-1a
  publicIP: eipalloc-0bbb
# after
- name: us-east-1a-private
  type: Private
  zone: us-east-1a
  publicIP: eipalloc-0aaa
- name: us-east-1a-private2
  type: Private
  zone: us-east-1a
  publicIP: eipalloc-0aaa
Defensive patterns

Strategy: validation

Validate before calling

#!/bin/bash
# Fail fast if publicIP values differ within a zone
kops get cluster -oyaml | yq '.spec.subnets | group_by(.zone) | .[] | select((map(.publicIP // "") | unique | length) > 1) | .[0].zone' | grep . && echo "mixed publicIP in zone" && exit 1 || true

Type guard

func uniformPublicIPPerZone(subnets []kops.ClusterSubnetSpec) bool {
    m := map[string]struct{}{}
    for _, s := range subnets {
        m[s.Zone+"|"+s.PublicIP] = struct{}{}
    }
    zones := map[string]struct{}{}
    for k := range m {
        zones[strings.SplitN(k, "|", 2)[0]] = struct{}{}
    }
    return len(m) == len(zones)
}

Try / catch

err := updateCluster(ctx)
if err != nil && strings.Contains(err.Error(), "cannot mix publicIP values") {
    // set the same publicIP on every private subnet in the offending zone, then re-run
}

Prevention

When it happens

Trigger: `kops update cluster` where two or more private/IPv6-capable subnets in the same zone specify different `publicIP` fields (e.g. one set to an existing EIP allocation string and another left empty or set to a different EIP).

Common situations: Reusing pre-created Elastic IPs across a zone but forgetting to set publicIP on every subnet block; templating that injects publicIP only into some subnets; adopting an existing cluster and annotating only part of the subnets.

Related errors


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