{"record":{"id":"276d589204950ad9","repo":"kubernetes/kops","slug":"unable-to-parse-disk-source-url-q","errorCode":null,"errorMessage":"unable to parse disk source URL: %q","messagePattern":"unable to parse disk source URL: %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/gcetasks/instance.go","lineNumber":134,"sourceCode":"\t\t\t// TODO: Parse source URL instead of assuming same project/zone?\n\t\t\tname := lastComponent(source)\n\t\t\td, err := cloud.Compute().Disks().Get(cloud.Project(), *e.Zone, name)\n\t\t\tif err != nil {\n\t\t\t\tif gce.IsNotFound(err) {\n\t\t\t\t\treturn nil, fmt.Errorf(\"disk not found %q: %v\", source, err)\n\t\t\t\t}\n\t\t\t\treturn nil, fmt.Errorf(\"error querying for disk %q: %v\", source, err)\n\t\t\t}\n\n\t\t\timage, err := ShortenImageURL(cloud.Project(), d.SourceImage)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"error parsing source image URL: %v\", err)\n\t\t\t}\n\t\t\tactual.Image = new(image)\n\t\t} else {\n\t\t\turl, err := gce.ParseGoogleCloudURL(disk.Source)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"unable to parse disk source URL: %q\", disk.Source)\n\t\t\t}\n\n\t\t\tactual.Disks[disk.DeviceName] = &Disk{Name: &url.Name}\n\t\t}\n\t}\n\n\tif r.Metadata != nil {\n\t\tactual.Metadata = make(map[string]fi.Resource)\n\t\tfor _, i := range r.Metadata.Items {\n\t\t\tactual.Metadata[i.Key] = fi.NewStringResource(fi.ValueOf(i.Value))\n\t\t}\n\t\tactual.metadataFingerprint = r.Metadata.Fingerprint\n\t}\n\n\treturn actual, nil\n}\n\nfunc (e *Instance) Run(c *fi.CloudupContext) error {","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/gcetasks/instance.go#L116-L152","documentation":"In Instance.Find, for attached (non-boot) disks whose source is not the instance's own project/zone path, kOps parses the disk source URL with gce.ParseGoogleCloudURL. This error is thrown when that URL cannot be parsed into its project/zone/name components, so the disk reference cannot be reconstructed in the actual state.","triggerScenarios":"disk.Source doesn't match the Google Cloud URL pattern expected by ParseGoogleCloudURL (e.g. truncated URL, regional/multi-region disk paths, custom formats, or manually attached disks with non-standard source strings).","commonSituations":"Manually attaching disks via API with shortened names instead of full URLs; disks attached from other regions with URL shapes the parser doesn't accept; drift where the instance's disk source changed after cluster creation.","solutions":["Print/inspect the instance's disk source: `gcloud compute instances describe <name> --zone=<zone> --format='value(disks[].source)'` and compare to what ParseGoogleCloudURL expects (full https://.../zones/<zone>/disks/<name> URL)","Re-attach the disk using its canonical full source URL","Update or remove the stale disk reference in the kops spec/state"],"exampleFix":"// before\nDisks().Insert(...).Source(\"my-disk\")\n// after\nDisks().Insert(...).Source(\"https://www.googleapis.com/compute/v1/projects/<proj>/zones/<zone>/disks/my-disk\")\n","handlingStrategy":"validation","validationCode":"// Ensure every attached disk source is a canonical full URL before Find\nfunc canonicalDiskSource(src string) bool {\n\tu := url.ParseOrEmpty(src)\n\treturn strings.HasSuffix(u.Path, \"/disks/\") && u.Name != \"\" && strings.Contains(u.Path, \"/zones/\")\n}","typeGuard":"func isParseableGCEURL(src string) bool {\n\t_, err := gce.ParseGoogleCloudURL(src)\n\treturn err == nil\n}","tryCatchPattern":null,"preventionTips":["Attach disks only with full canonical source URLs (https://www.googleapis.com/compute/v1/projects/.../disks/<name>)","Avoid manual disk surgery on kops-managed instances","Log disk.Source when parsing fails to spot format drift quickly","Keep attached disks in zones expressible by the URL parser"],"tags":["gce","disk","url-parsing"],"backgroundTag":"gce-url-parse-failed","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"}