{"record":{"id":"4abda5132d4d1887","repo":"kubernetes/kops","slug":"unable-to-determine-gcp-network-for-cluster","errorCode":null,"errorMessage":"unable to determine gcp network for cluster","messagePattern":"unable to determine gcp network for cluster","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/controllers/clusterapi/cluster_controller.go","lineNumber":137,"sourceCode":"\tgcpRegion := \"\"\n\tfor _, subnet := range s.Cluster.Spec.Subnets {\n\t\tif gcpRegion == \"\" {\n\t\t\tgcpRegion = subnet.Region\n\t\t} else if gcpRegion != subnet.Region {\n\t\t\treturn fmt.Errorf(\"found multiple gcp regions for cluster\")\n\t\t}\n\t}\n\tif gcpRegion == \"\" {\n\t\treturn fmt.Errorf(\"unable to determine gcp region for cluster\")\n\t}\n\n\t// TODO: Sync with LinkToNetwork\n\tgcpNetworkName := s.Cluster.Spec.NetworkID\n\tif gcpNetworkName == \"\" {\n\t\tgcpNetworkName = gce.SafeTruncatedClusterName(s.Cluster.ObjectMeta.Name, 63)\n\t}\n\tif gcpNetworkName == \"\" {\n\t\treturn fmt.Errorf(\"unable to determine gcp network for cluster\")\n\t}\n\n\tobj := map[string]any{\n\t\t\"apiVersion\": \"infrastructure.cluster.x-k8s.io/v1beta1\",\n\t\t\"kind\":       \"GCPCluster\",\n\t\t\"metadata\": map[string]any{\n\t\t\t\"name\":      name,\n\t\t\t\"namespace\": s.namespace(),\n\t\t},\n\t\t\"spec\": map[string]any{\n\t\t\t\"project\": gcpProject,\n\t\t\t\"region\":  gcpRegion,\n\t\t\t\"network\": map[string]any{\n\t\t\t\t\"name\": gcpNetworkName,\n\t\t\t},\n\t\t},\n\t}\n","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/controllers/clusterapi/cluster_controller.go#L119-L155","documentation":"applyGCPCluster falls back to deriving the network name from the cluster name when spec.networkID is empty; if even that fallback yields an empty string it fails with this error. The GCPCluster object needs a GCP network reference. In practice this is nearly unreachable, since SafeTruncatedClusterName derives from ObjectMeta.Name.","triggerScenarios":"clusterScope.Apply() where spec.networkID == '' and SafeTruncatedClusterName(cluster name) returns '' — effectively only when the Cluster has an empty metadata.name.","commonSituations":"Programmatically constructed Cluster objects with missing metadata.name; test fixtures; manifests corrupted before reconciliation.","solutions":["Set spec.networkID to the existing GCP VPC network name","Ensure Cluster metadata.name is populated","Re-run reconciliation after fixing the object"],"exampleFix":"// before\nspec:\n  subnets: [...]   # networkID missing\n// after\nspec:\n  networkID: my-vpc-network\n  subnets: [...]","handlingStrategy":"validation","validationCode":"if cluster.Spec.NetworkID == \"\" {\n\treturn fmt.Errorf(\"cluster %s: spec.networkID recommended; fallback only works if name is set\", cluster.Name)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set spec.networkID explicitly to the target VPC network","Ensure Cluster metadata.name is always populated","Validate objects programmatically before enqueueing for reconciliation"],"tags":["gcp","clusterapi","network"],"backgroundTag":"missing-gcp-network","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"}