{"record":{"id":"110453452666537a","repo":"kubernetes/kops","slug":"subnet-vpc-id-is-required","errorCode":null,"errorMessage":"Subnet.VPC.ID is required","messagePattern":"Subnet\\.VPC\\.ID is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/linodetasks/subnet.go","lineNumber":63,"sourceCode":"\t}\n\tid := strconv.Itoa(fi.ValueOf(v.ID))\n\treturn new(id)\n}\n\nfunc (v *Subnet) Find(c *fi.CloudupContext) (*Subnet, error) {\n\tcloud := c.T.Cloud.(linode.LinodeCloud)\n\n\tif v.VPC == nil {\n\t\treturn nil, fmt.Errorf(\"Subnet.VPC is required\")\n\t}\n\tif v.VPC.ID == nil {\n\t\tif v.VPC.Name != nil {\n\t\t\tif _, ok := c.Target.(*fi.CloudupDryRunTarget); ok {\n\t\t\t\treturn nil, nil\n\t\t\t}\n\t\t\treturn nil, fi.NewTryAgainLaterError(\"waiting for VPC ID\")\n\t\t}\n\t\treturn nil, fmt.Errorf(\"Subnet.VPC.ID is required\")\n\t}\n\n\tsubnets, err := cloud.Client().ListVPCSubnets(c.Context(), fi.ValueOf(v.VPC.ID), nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error listing Akamai (Linode) VPC Subnets: %w\", err)\n\t}\n\n\tvar foundByName *linodego.VPCSubnet\n\tvar foundByIPv4 *linodego.VPCSubnet\n\tname := fi.ValueOf(v.Name)\n\tipv4 := fi.ValueOf(v.IPv4)\n\tfor i := range subnets {\n\t\tcandidate := &subnets[i]\n\t\tif candidate.Label == name {\n\t\t\tif foundByName != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"found multiple Akamai (Linode) VPC Subnets named %q\", name)\n\t\t\t}\n\t\t\tfoundByName = candidate","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/linodetasks/subnet.go#L45-L81","documentation":"Subnet.Find validation guard: fires when the Subnet task has a VPC reference with neither ID nor Name set (or Name is nil). Without a VPC identifier the task cannot look up the subnet, so reconciliation is aborted with this sentinel validation error.","triggerScenarios":"v.VPC.ID == nil and v.VPC.Name == nil during Find(); the VPC reference was never resolved to an ID.","commonSituations":"Spec referencing a VPC only by an empty/missing identifier, or a broken dependency chain where the VPC task failed to populate its ID before the subnet task ran.","solutions":["Ensure the VPC task succeeds first so the subnet receives a resolved VPC ID","Fix the spec so the VPC is identified (by name, allowing dry-run/TryAgainLater, or by ID)","Check for earlier errors in the kops update log on the VPC creation step"],"exampleFix":"// before\nvpc: {}  // neither id nor name\n// after\nvpc: {name: my-cluster-vpc}  // lets Find wait for the ID","handlingStrategy":"validation","validationCode":"if vpc.ID == nil {\n    if vpc.Name == nil {\n        return errors.New(\"VPC reference needs either an ID or a name so it can be resolved\")\n    }\n    // name set: kops will wait; otherwise resolve the ID first\n}","typeGuard":"func vpcResolved(v *VPC) bool { return v != nil && (v.ID != nil || v.Name != nil) }","tryCatchPattern":"_, err := subnetTask.Find(c)\nif err != nil && strings.Contains(err.Error(), \"Subnet.VPC.ID is required\") {\n    // ensure the VPC task completes first, then retry the update\n    return err\n}","preventionTips":["Reference VPCs by name so kops can wait for ID assignment","Ensure VPC creation precedes subnet creation in ordering","Check earlier VPC task errors in the log"],"tags":["linode","akamai","subnet","vpc","validation"],"backgroundTag":"missing-required-argument","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"}