kubernetes/kops · error
unable to parse asset URL %q: %w
Error message
unable to parse asset URL %q: %w
What it means
buildFileAsset parses the canonical containerd-family asset URL with url.Parse before remapping. A malformed canonicalURL (from containerd/nerdctl/runc config) fails here and is wrapped with %w so the underlying parse error is preserved. It is the containerd-package equivalent of the CNI URL parse guard.
Source
Thrown at pkg/nodemodel/wellknownassets/containerd.go:98
}
var u string
switch arch {
case architectures.ArchitectureAmd64:
u = fmt.Sprintf(containerdReleaseUrlAmd64, version, version)
case architectures.ArchitectureArm64:
u = fmt.Sprintf(containerdReleaseUrlArm64, version, version)
default:
return nil, fmt.Errorf("unknown arch: %q", arch)
}
return url.Parse(u)
}
func buildFileAsset(assetBuilder *assets.AssetBuilder, canonicalURL string, knownHashString string) (*assets.FileAsset, error) {
u, err := url.Parse(canonicalURL)
if err != nil {
return nil, fmt.Errorf("unable to parse asset URL %q: %w", canonicalURL, err)
}
var knownHash *hashing.Hash
if knownHashString != "" {
h, err := hashing.FromString(knownHashString)
if err != nil {
return nil, fmt.Errorf("unable to parse asset hash %q: %w", knownHashString, err)
}
knownHash = h
}
asset, err := assetBuilder.RemapFile(u, knownHash)
if err != nil {
return nil, fmt.Errorf("unable to remap asset: %w", err)
}
return asset, nil
}View on GitHub (pinned to 4c8573c808)
Solutions
- Inspect the wrapped error for the exact position/syntax problem and correct the canonical URL in the cluster spec
- URL-encode special characters (spaces -> %20) in configured asset URLs
- Validate the configured URL with url.Parse or a validator before applying the cluster spec
- If using containerd.packages, point the URL fields at valid https tarball URLs
Example fix
// before url: "https://github.com/containerd/containerd/releases/download/v2.1.0/containerd 2.1.0.tar.gz" // after url: "https://github.com/containerd/containerd/releases/download/v2.1.0/containerd-2.1.0-linux-amd64.tar.gz"
Defensive patterns
Strategy: validation
Validate before calling
if _, err := url.Parse(canonicalURL); err != nil {
return fmt.Errorf("containerd asset URL %q is invalid: %v", canonicalURL, err)
} Try / catch
asset, err := wellknownassets.FindContainerdAsset(ig, assetBuilder, arch)
if err != nil && strings.Contains(err.Error(), "unable to parse asset URL") {
return fmt.Errorf("fix the configured containerd asset URL: %w", err)
} Prevention
- URL-encode special characters in configured asset URLs
- Validate all package URLs with url.Parse during manifest lint
- Copy URLs programmatically rather than by hand to avoid stray characters
When it happens
Trigger: FindContainerdAsset, FindNerdctlAsset, or FindRuncAsset pass a canonicalURL (often built from containerd.packages or custom URL settings) that url.Parse rejects — e.g. containing spaces, control characters, or a scheme-less malformed string.
Common situations: Custom package URLs in the cluster spec with typos or unencoded spaces; template expansion errors producing empty/garbled URLs; pasting URLs with surrounding quotes or trailing punctuation.
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 argument %q as url
- unable to find any containerd binaries in assets
- error finding contained version
- error parsing container runtime version %q: %w
- error building containerd flags: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/2013c608060b7a5a.
Report an issue: GitHub.