kubernetes/kops · error

subnet %s not found in VPC %s

Error message

subnet %s not found in VPC %s

What it means

After building a subnetByID map from the VPC's subnets, kOps looks up each user-supplied --subnets ID. If a subnet ID is not present in the specified VPC, "subnet %s not found in VPC %s" is returned. This guarantees that the subnets used for the cluster actually belong to the VPC the cluster will use.

Source

Thrown at upup/pkg/fi/cloudup/new_cluster.go:925

	awsCloud, err := awsup.NewAWSCloud(region, cloudTags)
	if err != nil {
		return res, fmt.Errorf("error loading cloud: %v", err)
	}
	vpcInfo, err := awsCloud.FindVPCInfo(VPCID)
	if err != nil {
		return res, fmt.Errorf("error describing VPC: %v", err)
	}
	if vpcInfo == nil {
		return res, fmt.Errorf("VPC %q not found", VPCID)
	}
	subnetByID := make(map[string]*fi.SubnetInfo)
	for _, subnetInfo := range vpcInfo.Subnets {
		subnetByID[subnetInfo.ID] = subnetInfo
	}
	for _, subnetID := range subnetIDs {
		subnet, ok := subnetByID[subnetID]
		if !ok {
			return res, fmt.Errorf("subnet %s not found in VPC %s", subnetID, VPCID)
		}
		if res[subnet.Zone] != "" {
			return res, fmt.Errorf("subnet %s and %s have the same zone", subnetID, res[subnet.Zone])
		}
		res[subnet.Zone] = subnetID
	}
	return res, nil
}

func getOpenstackZoneToSubnetProviderID(cluster *api.Cluster, zones []string, subnetIDs []string) (map[string]string, error) {
	res := make(map[string]string)
	osCloud, err := openstack.NewOpenstackCloud(cluster, "new-cluster-zone-to-subnet")
	if err != nil {
		return res, fmt.Errorf("error loading cloud: %v", err)
	}
	osCloud.UseZones(zones)

	networkInfo, err := osCloud.FindVPCInfo(cluster.Spec.Networking.NetworkID)

View on GitHub (pinned to 4c8573c808)

Solutions

  1. List the VPC's subnets: `aws ec2 describe-subnets --filters Name=vpc-id,Values=vpc-A --region <region>` and use only those IDs.
  2. Fix --subnets and --vpc so they are consistent (all subnets belong to --vpc).
  3. For cross-account shared subnets, ensure sharing is actually configured and the caller can describe them.

Example fix

// before
--vpc vpc-A --subnets subnet-fromVpcB
// after
--vpc vpc-A --subnets subnet-inVpcA-1,subnet-inVpcA-2
Defensive patterns

Strategy: validation

Validate before calling

out, _ := exec.Command("aws", "ec2", "describe-subnets", "--filters",
    "Name=vpc-id,Values="+vpcID, "--region", region, "--query",
    "Subnets[].SubnetId", "--output", "json").Output()
for _, s := range requestedSubnets {
    if !strings.Contains(string(out), s) {
        return fmt.Errorf("subnet %s is not in VPC %s", s, vpcID)
    }
}

Try / catch

if strings.Contains(err.Error(), "not found in VPC") {
    // re-run discovery of subnets belonging to the VPC and rebuild --subnets
}

Prevention

When it happens

Trigger: `kops create cluster --cloud aws --vpc vpc-A --subnets subnet-X ...` where subnet-X lives in VPC-B, a different region, a different account, or the ID is mistyped.

Common situations: Mixing subnets from default VPC and a custom VPC; cross-account subnet usage without sharing; typos in subnet IDs; subnets in a different region than the VPC.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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