kubernetes/kops · error

failed to get updates: %w

Error message

failed to get updates: %w

What it means

getUpdates compares each menu addon against installed channel versions via addon.GetRequiredUpdates. A per-addon error aborts the whole comparison and applyMenu wraps it as 'failed to get updates: %w', aborting before any changes are made.

Source

Thrown at channels/pkg/cmd/apply_channel.go:229

		}
		if err := applyMenu(ctx, menu, f.VFSContext(), k8sClient, cmClient, dynamicClient, restMapper, options.Yes); err != nil {
			merr = multierr.Append(merr, fmt.Errorf("applying %q: %w", channelLocation, err))
		}
	}
	return merr
}

func applyMenu(ctx context.Context, menu *channels.AddonMenu, vfsContext *vfs.VFSContext, k8sClient kubernetes.Interface, cmClient certmanager.Interface, dynamicClient dynamic.Interface, restMapper *restmapper.DeferredDiscoveryRESTMapper, apply bool) error {
	// channelVersions is the list of installed addons in the cluster.
	// It is keyed by <namespace>:<addon name>.
	channelVersions, err := getChannelVersions(ctx, k8sClient)
	if err != nil {
		return fmt.Errorf("cannot fetch channel versions from namespaces: %w", err)
	}

	updates, needUpdates, err := getUpdates(ctx, menu, k8sClient, cmClient, channelVersions)
	if err != nil {
		return fmt.Errorf("failed to get updates: %w", err)
	}

	if len(updates) == 0 {
		fmt.Printf("No update required\n")
		return nil
	}

	{
		t := &tables.Table{}
		t.AddColumn("NAME", func(r *channels.AddonUpdate) string {
			return r.Name
		})
		t.AddColumn("CURRENT", func(r *channels.AddonUpdate) string {
			if r.ExistingVersion == nil {
				return "-"
			}
			return r.ExistingVersion.ManifestHash
		})

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Identify the offending addon from the wrapped cause
  2. Fix or delete the in-cluster addon object with the malformed version/annotation
  3. Ensure the channel's addon.yaml declares valid semver versions
  4. Re-run apply after correcting in-cluster state
Defensive patterns

Strategy: validation

Validate before calling

for name, cv := range channelVersions {
	if cv != nil && cv.Version != "" {
		if _, err := semver.Parse(cv.Version); err != nil {
			return fmt.Errorf("addon %q has unparsable version %q; fix in-cluster state", name, cv.Version)
		}
	}
}

Type guard

func hasValidVersion(cv *channels.ChannelVersion) bool {
	if cv == nil || cv.Version == "" {
		return true
	}
	_, err := semver.Parse(cv.Version)
	return err == nil
}

Try / catch

updates, needUpdates, err := getUpdates(ctx, menu, k8sClient, cmClient, channelVersions)
if err != nil {
	return fmt.Errorf("aborting apply before changes; fix addon state: %w", err)
}

Prevention

When it happens

Trigger: During applyMenu, one addon's GetRequiredUpdates errors — usually fetching the installed addon object or parsing its version annotation.

Common situations: Corrupt or unparsable version annotation left by an older kOps version, missing/modified addon resource in-cluster, cert-manager client or API read errors.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/fd6c27d25203ef20. Report an issue: GitHub.