{"record":{"id":"56bceb2856b743ac","repo":"kubernetes/kops","slug":"could-not-find-public-subnet-in-zone-q","errorCode":null,"errorMessage":"could not find public subnet in zone: %q","messagePattern":"could not find public subnet in zone: %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/model/awsmodel/context.go","lineNumber":51,"sourceCode":"\tname := z.Name + \".\" + b.ClusterName()\n\n\treturn &awstasks.Subnet{Name: &name}\n}\n\nfunc (b *AWSModelContext) LinkToPublicSubnetInZone(zoneName string) (*awstasks.Subnet, error) {\n\tvar matches []*kops.ClusterSubnetSpec\n\tfor i := range b.Cluster.Spec.Networking.Subnets {\n\t\tz := &b.Cluster.Spec.Networking.Subnets[i]\n\t\tif z.Zone != zoneName {\n\t\t\tcontinue\n\t\t}\n\t\tif z.Type != kops.SubnetTypePublic {\n\t\t\tcontinue\n\t\t}\n\t\tmatches = append(matches, z)\n\t}\n\tif len(matches) == 0 {\n\t\treturn nil, fmt.Errorf(\"could not find public subnet in zone: %q\", zoneName)\n\t}\n\tif len(matches) > 1 {\n\t\t// TODO: Support this (arbitrary choice I think, for ELBs)\n\t\treturn nil, fmt.Errorf(\"found multiple public subnets in zone: %q\", zoneName)\n\t}\n\n\treturn b.LinkToSubnet(matches[0]), nil\n}\n\nfunc (b *AWSModelContext) LinkToUtilitySubnetInZone(zoneName string) (*awstasks.Subnet, error) {\n\tvar matches []*kops.ClusterSubnetSpec\n\tfor i := range b.Cluster.Spec.Networking.Subnets {\n\t\ts := &b.Cluster.Spec.Networking.Subnets[i]\n\t\tif s.Zone != zoneName {\n\t\t\tcontinue\n\t\t}\n\t\tif s.Type != kops.SubnetTypeUtility {\n\t\t\tcontinue","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/model/awsmodel/context.go#L33-L69","documentation":"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.","triggerScenarios":"`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.","commonSituations":"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.","solutions":["Add a public (or utility, per topology) subnet entry for the missing zone in spec.networking.subnets","Correct the zone field on the existing subnet so it matches the zone being linked (check for typos/region mismatches)","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"],"exampleFix":"// before (cluster.yaml) — no public subnet in us-east-1b\nsubnets:\n- name: public-a\n  type: public\n  zone: us-east-1a\n// after\nsubnets:\n- name: public-a\n  type: public\n  zone: us-east-1a\n- name: public-b\n  type: public\n  zone: us-east-1b","handlingStrategy":"validation","validationCode":"func hasPublicSubnetInZone(cluster *kops.Cluster, zone string) bool {\n    for _, s := range cluster.Spec.Networking.Subnets {\n        if s.Zone == zone && s.Type == kops.SubnetTypePublic {\n            return true\n        }\n    }\n    return false\n}","typeGuard":null,"tryCatchPattern":"subnet, err := b.LinkToPublicSubnetInZone(zone)\nif err != nil {\n    if strings.Contains(err.Error(), \"could not find public subnet in zone\") {\n        return fmt.Errorf(\"add a type:public subnet for zone %q to the cluster spec: %w\", zone, err)\n    }\n    return err\n}","preventionTips":["Ensure every zone used by instance groups/ELBs has exactly one public subnet (public topology) or utility subnet (private topology)","Double-check zone strings for typos and region consistency","Define subnet zone fields explicitly, never rely on defaults"],"tags":["kops","aws","subnet","topology","zone"],"backgroundTag":"public-subnet-not-found","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}