{"record":{"id":"390b935d767e9006","repo":"kubernetes/kops","slug":"unable-to-parse-cni-plugin-binaries-asset-url-q","errorCode":null,"errorMessage":"unable to parse CNI plugin binaries asset URL %q: %v","messagePattern":"unable to parse CNI plugin binaries asset URL %q: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/nodemodel/wellknownassets/cni.go","lineNumber":65,"sourceCode":"\tdefaultCNIAssetArm64K8s_36 = \"https://github.com/containernetworking/plugins/releases/download/v1.9.1/cni-plugins-linux-arm64-v1.9.1.tgz\"\n\n\t// Environment variable for overriding CNI url\n\tENV_VAR_CNI_ASSET_URL  = \"CNI_VERSION_URL\"\n\tENV_VAR_CNI_ASSET_HASH = \"CNI_ASSET_HASH_STRING\"\n)\n\nfunc FindCNIAssets(ig model.InstanceGroup, assetBuilder *assets.AssetBuilder, arch architectures.Architecture) (*assets.FileAsset, error) {\n\t// Override CNI packages from env vars\n\tcniAssetURL := os.Getenv(ENV_VAR_CNI_ASSET_URL)\n\tcniAssetHash := os.Getenv(ENV_VAR_CNI_ASSET_HASH)\n\n\tif cniAssetURL != \"\" && cniAssetHash != \"\" {\n\t\tklog.V(2).Infof(\"Using CNI asset URL %q, as set in %s\", cniAssetURL, ENV_VAR_CNI_ASSET_URL)\n\t\tklog.V(2).Infof(\"Using CNI asset hash %q, as set in %s\", cniAssetHash, ENV_VAR_CNI_ASSET_HASH)\n\n\t\tu, err := url.Parse(cniAssetURL)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"unable to parse CNI plugin binaries asset URL %q: %v\", cniAssetURL, err)\n\t\t}\n\n\t\th, err := hashing.FromString(cniAssetHash)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"unable to parse CNI plugin binaries asset hash %q: %v\", cniAssetHash, err)\n\t\t}\n\n\t\tasset, err := assetBuilder.RemapFile(u, h)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"unable to remap CNI plugin binaries asset: %v\", err)\n\t\t}\n\n\t\treturn asset, nil\n\t}\n\n\tswitch arch {\n\tcase architectures.ArchitectureAmd64:\n\t\tswitch {","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/nodemodel/wellknownassets/cni.go#L47-L83","documentation":"FindCNIAssets resolves the CNI plugin binaries tarball URL for a cluster's instance groups. When both CNI_VERSION_URL and CNI_ASSET_HASH_STRING env vars are set, it overrides the built-in defaults and parses the URL with net/url.Parse before remapping the asset. This error wraps a failure of url.Parse: the CNI_VERSION_URL value is not a valid URL (e.g. no scheme, control characters, or malformed).","triggerScenarios":"FindCNIAssets (via BuildKubernetesFileAssets) is called while os.Getenv(\"CNI_VERSION_URL\") and os.Getenv(\"CNI_ASSET_HASH_STRING\") are both non-empty, and url.Parse(cniAssetURL) returns a non-nil error.","commonSituations":"CNI_VERSION_URL set to a value without a scheme (e.g. \"containernetworking/plugins/download/x.tgz\"), a typo'd or truncated URL, a shell-interpolated variable that expanded to garbage, or a URL containing spaces/illegal characters from a CI config or Makefile.","solutions":["Print `echo $CNI_VERSION_URL` and fix it to a full absolute URL, e.g. https://github.com/containernetworking/plugins/releases/download/v1.6.2/cni-plugins-linux-amd64-v1.6.2.tgz","If you don't intend to override the CNI asset, unset CNI_VERSION_URL (and CNI_ASSET_HASH_STRING) so kOps uses its built-in defaults","Validate the URL with `url.Parse` or `python3 -c 'import urllib.parse; urllib.parse.urlparse(...)'` before exporting it in scripts/CI","Check quoting in shell/Makefile definitions so interpolation doesn't produce a malformed value"],"exampleFix":"// before\nexport CNI_VERSION_URL=\"containernetworking/plugins/releases/download/v1.6.2/cni-plugins-linux-amd64-v1.6.2.tgz\"\n// after\nexport CNI_VERSION_URL=\"https://github.com/containernetworking/plugins/releases/download/v1.6.2/cni-plugins-linux-amd64-v1.6.2.tgz\"","handlingStrategy":"validation","validationCode":"u := os.Getenv(\"CNI_VERSION_URL\")\nif u != \"\" {\n    if _, err := url.Parse(u); err != nil {\n        return fmt.Errorf(\"invalid %s: %w\", \"CNI_VERSION_URL\", err)\n    }\n}","typeGuard":"func isValidURL(s string) bool {\n    u, err := url.Parse(s)\n    return err == nil && u.Scheme != \"\" && u.Host != \"\"\n}","tryCatchPattern":"if _, err := FindCNIAssets(ig, assetBuilder, arch); err != nil {\n    if strings.Contains(err.Error(), \"unable to parse CNI plugin binaries asset URL\") {\n        klog.Errorf(\"check CNI_VERSION_URL env var: %v\", err)\n    }\n    return err\n}","preventionTips":["Always export CNI_VERSION_URL as an absolute https:// URL","Validate env vars at the top of CI scripts before invoking kOps","Unset the override vars when you don't need custom CNI assets"],"tags":["kops","cni","url-parsing","environment-variable","configuration"],"backgroundTag":"malformed-url","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"}