{"record":{"id":"a18c34ae3d185a8c","repo":"kubernetes/kops","slug":"error-parsing-source-image-url-v","errorCode":null,"errorMessage":"error parsing source image URL: %v","messagePattern":"error parsing source image URL: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/gcetasks/instance.go","lineNumber":128,"sourceCode":"\n\tactual.Disks = make(map[string]*Disk)\n\tfor i, disk := range r.Disks {\n\t\tif i == 0 {\n\t\t\tsource := disk.Source\n\n\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","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/gcetasks/instance.go#L110-L146","documentation":"After fetching the boot disk, kOps converts its fully-qualified SourceImage URL to a short image name using ShortenImageURL(project, d.SourceImage). This error is thrown when that URL cannot be shortened — typically the image URL comes from a different project with an unexpected format or the URL is empty/malformed.","triggerScenarios":"ShortenImageURL returns an error because d.SourceImage doesn't match expected 'projects/<project>/global/images/<name>' or 'https://.../projects/...' patterns — e.g. image family URLs, custom images from other projects, or empty SourceImage on a blank disk.","commonSituations":"Boot disk created from an image family or a shared image in another project; disk created manually without a source image (e.g. from a snapshot); GCE changing URL formats across API versions.","solutions":["Check the disk's SourceImage: `gcloud compute disks describe <disk> --zone=<zone> --format='value(sourceImage)'`","If the image lives in another project, ensure ShortenImageURL supports its URL form, or reference the image by its full path in the spec","If the disk has no source image (snapshot-created), populate kops state expectation accordingly or recreate the instance from a proper image"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Validate the disk's SourceImage URL shape before relying on ShortenImageURL\nfunc validSourceImage(url string) bool {\n\tif url == \"\" { return false }\n\treturn strings.Contains(url, \"/global/images/\") // projects/<p>/global/images/<name>\n}","typeGuard":"func isParseableImageURL(project, url string) bool {\n\t_, err := ShortenImageURL(project, url)\n\treturn err == nil\n}","tryCatchPattern":null,"preventionTips":["Provision instances from images referenced by full canonical URL in the same or known project","Avoid image-family or cross-project URLs unless ShortenImageURL handles that format","Check disks for empty SourceImage (snapshot-created disks) before deep refresh","Pin the image name in the kops spec rather than relying on family resolution"],"tags":["gce","image","url-parsing"],"backgroundTag":"gce-image-url-parse-failed","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}