{"record":{"id":"afc05697892df206","repo":"kubernetes/kops","slug":"unable-to-parse-cni-plugin-binaries-asset-hash-q","errorCode":null,"errorMessage":"unable to parse CNI plugin binaries asset hash %q: %v","messagePattern":"unable to parse CNI plugin binaries asset hash %q: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/nodemodel/wellknownassets/cni.go","lineNumber":70,"sourceCode":")\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 {\n\t\tcase ig.KubernetesVersion().IsGTE(\"1.36\"):\n\t\t\tcniAssetURL = defaultCNIAssetAmd64K8s_36\n\t\tcase ig.KubernetesVersion().IsGTE(\"1.35\"):\n\t\t\tcniAssetURL = defaultCNIAssetAmd64K8s_35\n\t\tcase ig.KubernetesVersion().IsGTE(\"1.34\"):","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/nodemodel/wellknownassets/cni.go#L52-L88","documentation":"When both CNI_VERSION_URL and CNI_ASSET_HASH_STRING env vars are set, FindCNIAssets converts CNI_ASSET_HASH_STRING via hashing.FromString, which expects a \"<algorithm>:<hex>\" format (e.g. sha256:<64 hex chars>). This error is thrown when the hash string cannot be parsed — wrong algorithm name, missing colon separator, or invalid hex.","triggerScenarios":"FindCNIAssets is called with CNI_ASSET_HASH_STRING set (and CNI_VERSION_URL set) to a value hashing.FromString rejects, such as a bare hex digest without the \"sha256:\" prefix, an unknown algorithm, or non-hex characters.","commonSituations":"User pasted only the raw sha256 digest from a release page without the \"sha256:\" prefix; used an unsupported algorithm name (md5, sha512) or misspelled one; env var picked up whitespace or quotes from a config file.","solutions":["Set CNI_ASSET_HASH_STRING in \"sha256:<hex>\" form, e.g. sha256:0e2a1a2c9b3d... (compute with `sha256sum <file>`)","Verify the hex portion is valid lowercase hex and matches the algorithm's expected length","If you don't need a custom hash override, unset CNI_ASSET_HASH_STRING (and CNI_VERSION_URL) to fall back to defaults"],"exampleFix":"// before\nexport CNI_ASSET_HASH_STRING=\"0e2a1a2c9b3d4e5f\"\n// after\nexport CNI_ASSET_HASH_STRING=\"sha256:0e2a1a2c9b3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f\"","handlingStrategy":"validation","validationCode":"h := os.Getenv(\"CNI_ASSET_HASH_STRING\")\nif h != \"\" {\n    parts := strings.SplitN(h, \":\", 2)\n    if len(parts) != 2 {\n        return fmt.Errorf(\"CNI_ASSET_HASH_STRING must be <algorithm>:<hex>, got %q\", h)\n    }\n    if _, err := hex.DecodeString(parts[1]); err != nil {\n        return fmt.Errorf(\"CNI_ASSET_HASH_STRING hex invalid: %w\", err)\n    }\n}","typeGuard":"func isAlgoPrefixedHash(s string) bool {\n    i := strings.Index(s, \":\")\n    if i <= 0 || i == len(s)-1 {\n        return false\n    }\n    _, err := hex.DecodeString(s[i+1:])\n    return err == nil\n}","tryCatchPattern":"if _, err := FindCNIAssets(ig, assetBuilder, arch); err != nil {\n    if strings.Contains(err.Error(), \"unable to parse CNI plugin binaries asset hash\") {\n        klog.Errorf(\"CNI_ASSET_HASH_STRING must look like sha256:<64 hex chars>: %v\", err)\n    }\n    return err\n}","preventionTips":["Always include the \"sha256:\" prefix, not just the raw digest","Generate the value with `sha256sum file | awk '{print \"sha256:\"$1}'`","Trim whitespace/quotes when exporting from config files"],"tags":["kops","cni","hashing","environment-variable","configuration"],"backgroundTag":"invalid-hash-format","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"}