kubernetes/kops · error
image has no sources: %v
Error message
image has no sources: %v
What it means
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.
Source
Thrown at upup/pkg/fi/nodeup/command.go:346
loader.Builders = append(loader.Builders, &model.AzureBuilder{NodeupModelContext: modelContext})
loader.Builders = append(loader.Builders, &model.LinodeBuilder{NodeupModelContext: modelContext})
loader.Builders = append(loader.Builders, &networking.CommonBuilder{NodeupModelContext: modelContext})
loader.Builders = append(loader.Builders, &networking.CalicoBuilder{NodeupModelContext: modelContext})
loader.Builders = append(loader.Builders, &networking.CiliumBuilder{NodeupModelContext: modelContext})
loader.Builders = append(loader.Builders, &networking.KindnetBuilder{NodeupModelContext: modelContext})
loader.Builders = append(loader.Builders, &networking.AmazonVPCRoutedENIBuilder{NodeupModelContext: modelContext})
loader.Builders = append(loader.Builders, &networking.KuberouterBuilder{NodeupModelContext: modelContext})
loader.Builders = append(loader.Builders, &model.BootstrapClientBuilder{NodeupModelContext: modelContext})
taskMap, err := loader.Build()
if err != nil {
return fmt.Errorf("error building loader: %v", err)
}
for _, image := range nodeupConfig.Images[architecture] {
if len(image.Sources) == 0 {
return fmt.Errorf("image has no sources: %v", image)
}
u, err := url.Parse(image.Sources[0])
if err != nil {
return fmt.Errorf("invalid image source URL %q: %w", image.Sources[0], err)
}
key := "SideloadImage/" + path.Base(u.Path)
if _, ok := taskMap[key]; ok {
return fmt.Errorf("duplicate image task %q", key)
}
taskMap[key] = &nodetasks.LoadImageTask{
Sources: image.Sources,
Hash: image.Hash,
}
}
var target fi.NodeupTarget
switch c.Target {View on GitHub (pinned to 4c8573c808)
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
Example fix
// before: image entry in NodeupConfig
// {"name":"pause","sources":[]}
// after
// {"name":"pause","sources":["https://registry.k8s.io/pause:3.9"]} Defensive patterns
Strategy: validation
Validate before calling
for arch, imgs := range nodeupConfig.Images {
for i, img := range imgs {
if len(img.Sources) == 0 {
return fmt.Errorf("nodeupConfig.Images[%s][%d] has no sources", arch, i)
}
}
} Type guard
func imageHasSources(img NodeupImage) bool { return len(img.Sources) > 0 } Try / catch
if err := nodeupCmd.Run(ctx); err != nil {
if strings.Contains(err.Error(), "image has no sources") {
log.Fatalf("bad image config: %v — regenerate NodeupConfig", err)
}
return err
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- invalid image source URL %q: %w
- duplicate image task %q
- error building context: %w
- building nodeConfig for instanceGroup: %w
- marshalling nodeupConfig: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/b65e7b0931f50726.
Report an issue: GitHub.