kubernetes/kops · error
unable to parse disk source URL: %q
Error message
unable to parse disk source URL: %q
What it means
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.
Source
Thrown at upup/pkg/fi/cloudup/gcetasks/instance.go:134
// TODO: Parse source URL instead of assuming same project/zone?
name := lastComponent(source)
d, err := cloud.Compute().Disks().Get(cloud.Project(), *e.Zone, name)
if err != nil {
if gce.IsNotFound(err) {
return nil, fmt.Errorf("disk not found %q: %v", source, err)
}
return nil, fmt.Errorf("error querying for disk %q: %v", source, err)
}
image, err := ShortenImageURL(cloud.Project(), d.SourceImage)
if err != nil {
return nil, fmt.Errorf("error parsing source image URL: %v", err)
}
actual.Image = new(image)
} else {
url, err := gce.ParseGoogleCloudURL(disk.Source)
if err != nil {
return nil, fmt.Errorf("unable to parse disk source URL: %q", disk.Source)
}
actual.Disks[disk.DeviceName] = &Disk{Name: &url.Name}
}
}
if r.Metadata != nil {
actual.Metadata = make(map[string]fi.Resource)
for _, i := range r.Metadata.Items {
actual.Metadata[i.Key] = fi.NewStringResource(fi.ValueOf(i.Value))
}
actual.metadataFingerprint = r.Metadata.Fingerprint
}
return actual, nil
}
func (e *Instance) Run(c *fi.CloudupContext) error {View on GitHub (pinned to 4c8573c808)
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
Example fix
// before
Disks().Insert(...).Source("my-disk")
// after
Disks().Insert(...).Source("https://www.googleapis.com/compute/v1/projects/<proj>/zones/<zone>/disks/my-disk")
Defensive patterns
Strategy: validation
Validate before calling
// Ensure every attached disk source is a canonical full URL before Find
func canonicalDiskSource(src string) bool {
u := url.ParseOrEmpty(src)
return strings.HasSuffix(u.Path, "/disks/") && u.Name != "" && strings.Contains(u.Path, "/zones/")
} Type guard
func isParseableGCEURL(src string) bool {
_, err := gce.ParseGoogleCloudURL(src)
return err == nil
} Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- unable to parse instance url %q
- invalid google cloud URL (content after name): %q
- error parsing subnet url %q: %w
- error parsing operation URL %q: %v
- error during Disk creation: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/276d589204950ad9.
Report an issue: GitHub.