{"record":{"id":"b65e7b0931f50726","repo":"kubernetes/kops","slug":"image-has-no-sources-v","errorCode":null,"errorMessage":"image has no sources: %v","messagePattern":"image has no sources: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/nodeup/command.go","lineNumber":346,"sourceCode":"\tloader.Builders = append(loader.Builders, &model.AzureBuilder{NodeupModelContext: modelContext})\n\tloader.Builders = append(loader.Builders, &model.LinodeBuilder{NodeupModelContext: modelContext})\n\n\tloader.Builders = append(loader.Builders, &networking.CommonBuilder{NodeupModelContext: modelContext})\n\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 {","sourceCodeStart":328,"sourceCodeEnd":364,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/nodeup/command.go#L328-L364","documentation":"Run() iterates nodeupConfig.Images[architecture] and creates a LoadImageTask for each container image to sideload. If an image entry has an empty Sources list, nodeup rejects it outright because a LoadImageTask with no source cannot pull or sideload anything. This indicates malformed image config in the NodeupConfig.","triggerScenarios":"An entry in nodeupConfig.Images[architecture] has len(image.Sources) == 0 — i.e. the images map for the node's architecture contains an image with no source URLs.","commonSituations":"Hand-edited or template-generated nodeup config where the image source list was dropped; cluster spec with custom images configured incorrectly; arch mismatch so the wrong architecture bucket is populated; older kops versions producing configs consumed by newer nodeup.","solutions":["Inspect the NodeupConfig Images map for the node's architecture and fix/remove entries with empty Sources","Regenerate the cluster config with `kops update cluster` so image lists are repopulated from the kops version defaults","Ensure any containerd_config/images overrides in the cluster spec include full source URLs","Align nodeup binary version with the kops version that rendered the config"],"exampleFix":"// before: image entry in NodeupConfig\n// {\"name\":\"pause\",\"sources\":[]}\n// after\n// {\"name\":\"pause\",\"sources\":[\"https://registry.k8s.io/pause:3.9\"]}","handlingStrategy":"validation","validationCode":"for arch, imgs := range nodeupConfig.Images {\n    for i, img := range imgs {\n        if len(img.Sources) == 0 {\n            return fmt.Errorf(\"nodeupConfig.Images[%s][%d] has no sources\", arch, i)\n        }\n    }\n}","typeGuard":"func imageHasSources(img NodeupImage) bool { return len(img.Sources) > 0 }","tryCatchPattern":"if err := nodeupCmd.Run(ctx); err != nil {\n    if strings.Contains(err.Error(), \"image has no sources\") {\n        log.Fatalf(\"bad image config: %v — regenerate NodeupConfig\", err)\n    }\n    return err\n}","preventionTips":["Never hand-edit the images map in NodeupConfig; use the cluster spec","Validate custom image entries include full https URLs before `kops update`","Confirm the arch bucket matches the node architecture (amd64/arm64)","Diff generated nodeup config after kops upgrades"],"tags":["nodeup","images","config-validation"],"backgroundTag":"missing-image-source","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"}