{"record":{"id":"1f005cddb8ae9321","repo":"kubernetes/kops","slug":"invalid-image-source-url-q-w","errorCode":null,"errorMessage":"invalid image source URL %q: %w","messagePattern":"invalid image source URL %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/nodeup/command.go","lineNumber":350,"sourceCode":"\tloader.Builders = append(loader.Builders, &networking.CalicoBuilder{NodeupModelContext: modelContext})\n\tloader.Builders = append(loader.Builders, &networking.CiliumBuilder{NodeupModelContext: modelContext})\n\tloader.Builders = append(loader.Builders, &networking.KindnetBuilder{NodeupModelContext: modelContext})\n\tloader.Builders = append(loader.Builders, &networking.AmazonVPCRoutedENIBuilder{NodeupModelContext: modelContext})\n\tloader.Builders = append(loader.Builders, &networking.KuberouterBuilder{NodeupModelContext: modelContext})\n\n\tloader.Builders = append(loader.Builders, &model.BootstrapClientBuilder{NodeupModelContext: modelContext})\n\ttaskMap, err := loader.Build()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error building loader: %v\", err)\n\t}\n\n\tfor _, image := range nodeupConfig.Images[architecture] {\n\t\tif len(image.Sources) == 0 {\n\t\t\treturn fmt.Errorf(\"image has no sources: %v\", image)\n\t\t}\n\t\tu, err := url.Parse(image.Sources[0])\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"invalid image source URL %q: %w\", image.Sources[0], err)\n\t\t}\n\t\tkey := \"SideloadImage/\" + path.Base(u.Path)\n\t\tif _, ok := taskMap[key]; ok {\n\t\t\treturn fmt.Errorf(\"duplicate image task %q\", key)\n\t\t}\n\t\ttaskMap[key] = &nodetasks.LoadImageTask{\n\t\t\tSources: image.Sources,\n\t\t\tHash:    image.Hash,\n\t\t}\n\t}\n\n\tvar target fi.NodeupTarget\n\n\tswitch c.Target {\n\tcase \"direct\":\n\t\ttarget = &local.LocalTarget{\n\t\t\tCacheDir: c.CacheDir,\n\t\t\tCloud:    cloud,","sourceCodeStart":332,"sourceCodeEnd":368,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/nodeup/command.go#L332-L368","documentation":"For each configured sideload image, Run() parses image.Sources[0] with net/url. If url.Parse fails, nodeup wraps the parse error as \"invalid image source URL\". This almost always means the first source string is not a syntactically valid URL (control characters, malformed scheme, etc.).","triggerScenarios":"url.Parse(image.Sources[0]) returns an error for an entry in nodeupConfig.Images[architecture].","commonSituations":"Typo or unescaped characters in a custom image source; template substitution leaving placeholder text like {{ .registry }} in the URL; newline/whitespace corruption in generated nodeup config.","solutions":["Look at the quoted URL in the error and fix the malformed source in the NodeupConfig / cluster spec","Remove placeholder text or unescaped characters and re-render the config with `kops update cluster`","Validate image source URLs with `url.Parse` semantics (e.g. quick check in Go or curl) before committing custom images","Ensure the registry mirror/proxy URL used in the cluster spec is a valid absolute URL"],"exampleFix":"// before\n// \"sources\": [\"registry.example.com/{{ .cluster }}/pause:3.9\"]\n// after (rendered)\n// \"sources\": [\"registry.example.com/mycluster/pause:3.9\"]","handlingStrategy":"validation","validationCode":"if _, err := url.Parse(image.Sources[0]); err != nil {\n    return fmt.Errorf(\"image %q source %q is not a valid URL\", image.Name, image.Sources[0])\n}","typeGuard":"func validImageSource(src string) bool {\n    u, err := url.Parse(src)\n    return err == nil && u.Scheme != \"\" && u.Host != \"\"\n}","tryCatchPattern":"if err := nodeupCmd.Run(ctx); err != nil {\n    if strings.Contains(err.Error(), \"invalid image source URL\") {\n        var urlErr error\n        errors.As(err, &urlErr)\n        log.Fatalf(\"fix image source in cluster spec: %v\", urlErr)\n    }\n    return err\n}","preventionTips":["Avoid raw template placeholders in image source URLs","Sanitize/trim whitespace and newlines when templating registry URLs","Validate URLs in CI before applying cluster spec changes","Prefer mirror configs (containerd mirrors) over rewriting source URLs by hand"],"tags":["nodeup","images","url","config-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"}