kubernetes/kops · error

legacy addons are deprecated and unmaintained, use managed a

Error message

legacy addons are deprecated and unmaintained, use managed addons instead of %s

What it means

buildMenu rejects relative (non-absolute) channel locations because they resolve to the legacy well-known addons location (raw.githubusercontent.com/kubernetes/kops/master/addons/<name>/addon.yaml). Legacy addons are deprecated and unmaintained since Kubernetes 1.23, so the tool refuses and names the expanded legacy URL.

Source

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

		for name, version := range addons {
			channelVersions[ns.Name+":"+name] = version
		}
	}
	return channelVersions, nil
}

func buildMenu(vfsContext *vfs.VFSContext, kubernetesVersion semver.Version, channelLocation string) (*channels.AddonMenu, error) {
	menu := channels.NewAddonMenu()

	location, err := url.Parse(channelLocation)
	if err != nil {
		return nil, fmt.Errorf("unable to parse argument %q as url", channelLocation)
	}
	if !location.IsAbs() {
		expanded := "https://raw.githubusercontent.com/kubernetes/kops/master/addons/" + channelLocation + "/addon.yaml"
		// Disallow the use of legacy addons from the "well-known" location starting Kubernetes 1.23:
		// https://raw.githubusercontent.com/kubernetes/kops/master/addons/<name>/addon.yaml
		return nil, fmt.Errorf("legacy addons are deprecated and unmaintained, use managed addons instead of %s", expanded)
	}
	o, err := channels.LoadAddons(vfsContext, channelLocation, location)
	if err != nil {
		return nil, fmt.Errorf("error loading channel %q: %v", location, err)
	}

	current, err := o.GetCurrent(kubernetesVersion)
	if err != nil {
		return nil, fmt.Errorf("error processing latest versions in %q: %v", location, err)
	}
	menu.MergeAddons(current)
	return menu, nil
}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Replace the legacy addon with a kOps managed addon (spec.addons in the cluster spec)
  2. Use an absolute https:// URL to a maintained addon manifest instead of the bare name
  3. Consult kOps >= 1.23 docs for the managed-addon equivalent
  4. Do not bypass the check; legacy manifests are unmaintained

Example fix

// before
kops apply channel networking.flannel
// after
kops edit cluster  # spec.addons:
# - manifest: https://example.com/addons/networking.addons.k8s.io/addon.yaml
kops update cluster --yes
Defensive patterns

Strategy: validation

Validate before calling

u, err := url.Parse(channelLocation)
if err == nil && !u.IsAbs() {
	return fmt.Errorf("%q is a legacy addon name; use managed addons or an absolute manifest URL", channelLocation)
}

Type guard

func isAbsoluteURL(s string) bool {
	u, err := url.Parse(s)
	return err == nil && u.IsAbs()
}

Try / catch

if err := RunApplyChannel(ctx, f, out, args, options); err != nil && strings.Contains(err.Error(), "legacy addons are deprecated") {
	return fmt.Errorf("migrate %v to spec.addons managed addons instead", args)
}

Prevention

When it happens

Trigger: Running `kops apply channel <name>` with a bare/relative addon name (e.g. networking.flannel) — anything that parses as a URL but is not absolute.

Common situations: Following pre-1.23 kOps docs or tutorials listing legacy addons, migrating old automation scripts, habitually typing short addon names.

Related errors


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