{"record":{"id":"52fd9c79d3c87d5c","repo":"kubernetes/kops","slug":"file-url-is-not-defined","errorCode":null,"errorMessage":"file url is not defined","messagePattern":"file url is not defined","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/assets/builder.go","lineNumber":378,"sourceCode":"\t// If the phase is \"assets\" we use the CanonicalFileURL,\n\t// but during other phases we use the hash from the FileRepository or the base kops path.\n\t// We do not want to just test for CanonicalFileURL as it is defined in\n\t// other phases, but is not used to test for the SHA.\n\t// This prevents a chicken and egg problem where the file is not yet in the FileRepository.\n\t//\n\t// assets phase -> get the sha file from the source / CanonicalFileURL\n\t// any other phase -> get the sha file from the kops base location or the FileRepository\n\t//\n\t// TLDR; we use the file.CanonicalFileURL during assets phase, and use file.FileUrl the\n\t// rest of the time. If not we get a chicken and the egg problem where we are reading the sha file\n\t// before it exists.\n\tu := file.DownloadURL\n\tif a.getAssets {\n\t\tu = file.CanonicalURL\n\t}\n\n\tif u == nil {\n\t\treturn nil, fmt.Errorf(\"file url is not defined\")\n\t}\n\n\tknownHash, found, err := assetdata.GetHash(file.CanonicalURL)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif found {\n\t\treturn knownHash, nil\n\t}\n\n\tif cachedHash, found := downloadedFileHashes.Load(u.String()); found {\n\t\tklog.V(8).Infof(\"using cached hash for %q\", u)\n\t\treturn cachedHash.(*hashing.Hash), nil\n\t}\n\n\tklog.V(2).Infof(\"asset %q is not well-known, downloading hash\", file.CanonicalURL)\n\n\t// We now prefer sha256 hashes","sourceCodeStart":360,"sourceCodeEnd":396,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/assets/builder.go#L360-L396","documentation":"findHash requires a URL to look up the file's hash: it uses DownloadURL (or CanonicalURL when getAssets is set). If the FileAsset has neither URL set, hashing is impossible, so it fails with this message.","triggerScenarios":"RemapFile/FindFileAsset flow constructing a FileAsset with nil DownloadURL and nil CanonicalURL, then calling findHash.","commonSituations":"Misconfigured asset builder where base download URLs were never populated; custom code paths building FileAsset structs manually without setting URLs.","solutions":["Set CanonicalURL (and DownloadURL) on the FileAsset before hashing.","Verify the AssetBuilder inputs (KubernetesVersion, asset mirrors) that produce these URLs.","If calling findHash indirectly, ensure the source URL string parsed successfully (non-nil *url.URL)."],"exampleFix":"// before\nfileAsset := &FileAsset{} // no URLs\nhash, err := findHash(fileAsset)\n// after\ncanonical, err := url.Parse(\"https://storage.googleapis.com/kubernetes-release/release/v1.28.0/bin/linux/amd64/kubelet\")\nif err != nil {\n\treturn nil, err\n}\nfileAsset := &FileAsset{CanonicalURL: canonical, DownloadURL: canonical}\nhash, err := findHash(fileAsset)","handlingStrategy":"validation","validationCode":"func fileAssetReady(f *assets.FileAsset) error {\n\tif f.DownloadURL == nil && f.CanonicalURL == nil {\n\t\treturn fmt.Errorf(\"FileAsset has no DownloadURL or CanonicalURL\")\n\t}\n\treturn nil\n}","typeGuard":"func hasURL(f *assets.FileAsset) bool { return f != nil && (f.DownloadURL != nil || f.CanonicalURL != nil) }","tryCatchPattern":"if err := fileAssetReady(fileAsset); err != nil { return err }\nhash, err := findHash(fileAsset)\nif err != nil {\n\tif strings.Contains(err.Error(), \"file url is not defined\") {\n\t\treturn fmt.Errorf(\"file %s: URL fields missing on FileAsset\", fileAsset.CanonicalURL)\n\t}\n\treturn err\n}","preventionTips":["Always set CanonicalURL when constructing FileAsset structs.","Verify url.Parse succeeded (err == nil) before storing the URL.","Keep getAssets mode consistent with which URL field you populate."],"tags":["assets","hashing","url"],"backgroundTag":"missing-file-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"}