{"record":{"id":"885409139a660628","repo":"kubernetes/kops","slug":"invalud-url-for-file-q-v","errorCode":null,"errorMessage":"Invalud URL for file %q: %v","messagePattern":"Invalud URL for file %q: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/http.go","lineNumber":87,"sourceCode":"\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif err := os.Chmod(tempPath, 0o644); err != nil {\n\t\treturn nil, fmt.Errorf(\"error setting mode on downloaded file %q: %v\", tempPath, err)\n\t}\n\tif err := os.Rename(tempPath, destPath); err != nil {\n\t\treturn nil, fmt.Errorf(\"error moving downloaded file %q to %q: %v\", tempPath, destPath, err)\n\t}\n\treturn actual, nil\n}\n\n// downloadURLToWriter streams the file at the given url to dest.\n// If hash is non-nil, it will also verify that it matches the downloaded bytes.\nfunc downloadURLToWriter(ctx context.Context, desturl string, dest io.Writer, hash *hashing.Hash) (*hashing.Hash, error) {\n\tu, err := url.Parse(desturl)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"Invalud URL for file %q: %v\", desturl, err)\n\t}\n\n\tstart := time.Now()\n\tdefer func() {\n\t\tklog.V(2).Infof(\"Downloading %q took %q\", desturl, time.Since(start))\n\t}()\n\tklog.V(2).Infof(\"Downloading %q\", desturl)\n\n\talgorithm := hashing.HashAlgorithmSHA256\n\tif hash != nil {\n\t\talgorithm = hash.Algorithm\n\t}\n\thasher := algorithm.NewHasher()\n\twriter := io.MultiWriter(dest, hasher)\n\n\tswitch u.Scheme {\n\tcase \"gs\", \"s3\", \"azureblob\":\n\t\t// vfs resolves the bucket and signs the request with the ambient cloud credentials,","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/http.go#L69-L105","documentation":"downloadURLToWriter parses the source URL with url.Parse before fetching it. Any malformed URL is reported with this (typo'd 'Invalud') message. Note: url.Parse is lenient — this fires only for structurally invalid URLs.","triggerScenarios":"url.Parse(desturl) returns an error: control characters in the URL, malformed percent-encoding, or otherwise unparsable scheme/path.","commonSituations":"Cluster spec references an asset URL with embedded spaces/newlines or bad escapes (e.g. %zz) in kops_spec assets, base images, or mirror configuration.","solutions":["Inspect the wrapped %v error for the exact parse failure and character offset","Correct the URL in your cluster spec / asset configuration","Re-run the command with the fixed URL"],"exampleFix":"// before\nurl: \"https://example.com/path%zzfile.tgz\"\n// after\nurl: \"https://example.com/path%7Bfile%7D.tgz\"","handlingStrategy":"validation","validationCode":"u, err := url.Parse(assetURL)\nif err != nil || u.Scheme == \"\" || u.Host == \"\" {\n    return fmt.Errorf(\"asset URL is not an absolute valid URL: %q\", assetURL)\n}","typeGuard":null,"tryCatchPattern":"if _, err := fi.DownloadURL(ctx, assetURL, dest, nil); err != nil {\n    if strings.Contains(err.Error(), \"Invalud URL\") {\n        return fmt.Errorf(\"fix the malformed URL in your spec: %w\", err)\n    }\n    return err\n}","preventionTips":["Validate all asset/mirror URLs in the cluster spec with url.Parse before apply","Avoid hand-editing URLs; use tooling that percent-encodes paths","Lint cluster specs for stray whitespace/control characters in URLs"],"tags":["url","download","validation"],"backgroundTag":"invalid-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"}