kubernetes/kops · error

could not find public subnet in zone: %q

Error message

could not find public subnet in zone: %q

What it means

AWSModelContext.LinkToPublicSubnetInZone scans the cluster's subnets for one in the given zone with type "public"; if none exists it returns this error. Callers (e.g. the bastion/AWS model builders) need a public subnet reference in each zone to attach ELBs/NLBs or resources that must be internet-facing.

Source

Thrown at pkg/model/awsmodel/context.go:51

	name := z.Name + "." + b.ClusterName()

	return &awstasks.Subnet{Name: &name}
}

func (b *AWSModelContext) LinkToPublicSubnetInZone(zoneName string) (*awstasks.Subnet, error) {
	var matches []*kops.ClusterSubnetSpec
	for i := range b.Cluster.Spec.Networking.Subnets {
		z := &b.Cluster.Spec.Networking.Subnets[i]
		if z.Zone != zoneName {
			continue
		}
		if z.Type != kops.SubnetTypePublic {
			continue
		}
		matches = append(matches, z)
	}
	if len(matches) == 0 {
		return nil, fmt.Errorf("could not find public subnet in zone: %q", zoneName)
	}
	if len(matches) > 1 {
		// TODO: Support this (arbitrary choice I think, for ELBs)
		return nil, fmt.Errorf("found multiple public subnets in zone: %q", zoneName)
	}

	return b.LinkToSubnet(matches[0]), nil
}

func (b *AWSModelContext) LinkToUtilitySubnetInZone(zoneName string) (*awstasks.Subnet, error) {
	var matches []*kops.ClusterSubnetSpec
	for i := range b.Cluster.Spec.Networking.Subnets {
		s := &b.Cluster.Spec.Networking.Subnets[i]
		if s.Zone != zoneName {
			continue
		}
		if s.Type != kops.SubnetTypeUtility {
			continue

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Add a public (or utility, per topology) subnet entry for the missing zone in spec.networking.subnets
  2. Correct the zone field on the existing subnet so it matches the zone being linked (check for typos/region mismatches)
  3. If the topology is fully private and no public subnet is intended, remove the component requiring one (e.g. the bastion instance group) or switch the bastion LB to internal with appropriate subnets

Example fix

// before (cluster.yaml) — no public subnet in us-east-1b
subnets:
- name: public-a
  type: public
  zone: us-east-1a
// after
subnets:
- name: public-a
  type: public
  zone: us-east-1a
- name: public-b
  type: public
  zone: us-east-1b
Defensive patterns

Strategy: validation

Validate before calling

func hasPublicSubnetInZone(cluster *kops.Cluster, zone string) bool {
    for _, s := range cluster.Spec.Networking.Subnets {
        if s.Zone == zone && s.Type == kops.SubnetTypePublic {
            return true
        }
    }
    return false
}

Try / catch

subnet, err := b.LinkToPublicSubnetInZone(zone)
if err != nil {
    if strings.Contains(err.Error(), "could not find public subnet in zone") {
        return fmt.Errorf("add a type:public subnet for zone %q to the cluster spec: %w", zone, err)
    }
    return err
}

Prevention

When it happens

Trigger: `kops update cluster`/model build for a cluster where a zone that requires a public subnet (e.g. bastion or public ELB placement) contains only private/utility subnets, or the zone name passed (often a bastion instance group's zone or a mistranscribed zone) has no matching public subnet entry.

Common situations: Private-topology clusters where the user expected the bastion to work without utility/public subnets, typos in zone names (us-east-1b vs us-east-1a), subnets defined without a zone field, or deleting the public subnet block while keeping public-facing components.

Related errors


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