kubernetes/kops · error

failed to annotate %q: %w

Error message

failed to annotate %q: %w

What it means

RemapAddonManifest wraps any failure from addLabels — which stamps kops ownership labels and verifies the addon's selector labels on every object in the manifest — with this contextual error naming the addon. It is a wrapper: the root cause is one of the addLabels failures (metadata reparse failure, conflicting selector label).

Source

Thrown at pkg/model/components/addonmanifests/remap.go:56

func RemapAddonManifest(addon *addonsapi.AddonSpec, context *model.KopsModelContext, assetBuilder *assets.AssetBuilder, manifest []byte, serviceAccounts map[types.NamespacedName]iam.Subject) ([]byte, error) {
	name := fi.ValueOf(addon.Name)

	{
		objects, err := kubemanifest.LoadObjectsFrom(manifest)
		if err != nil {
			return nil, err
		}

		if name == "dns-controller.addons.k8s.io" {
			if err := dnscontroller.Remap(context, addon, objects); err != nil {
				return nil, err
			}
		}

		err = addLabels(addon, objects)
		if err != nil {
			return nil, fmt.Errorf("failed to annotate %q: %w", name, err)
		}

		err = addServiceAccountRole(context, objects, serviceAccounts)
		if err != nil {
			return nil, fmt.Errorf("failed to add service account for %q: %w", name, err)
		}

		b, err := objects.ToYAML()
		if err != nil {
			return nil, err
		}
		manifest = b
	}

	{
		remapped, err := assetBuilder.RemapManifest(manifest)
		if err != nil {
			return nil, fmt.Errorf("error remapping manifest %s: %v", name, err)

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Read the wrapped inner error to identify which object/label conflicted
  2. Remove or correct conflicting labels so they match the addon's selector in the Addon spec
  3. Fix malformed metadata in the manifest so it parses as metav1.ObjectMeta
  4. Restore the stock manifest for the addon from the matching kops channel

Example fix

# before
metadata:
  labels:
    addon.kops.k8s.io/name: my-custom-dns-controller
# after (match the addon spec selector)
metadata:
  labels:
    addon.kops.k8s.io/name: dns-controller.addons.k8s.io
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check selector labels on each object before remapping:
meta := &metav1.ObjectMeta{}
if err := object.Reparse(meta, "metadata"); err != nil { return err }
for k, v := range addon.Selector {
    if existing, ok := meta.Labels[k]; ok && existing != v {
        return fmt.Errorf("pre-check: label %q=%q conflicts with selector %q", k, existing, v)
    }
}

Try / catch

if _, err := RemapAddonManifest(addon, ctx, ab, manifest, sas); err != nil {
    var wrapped interface{ Unwrap() error }
    if errors.As(err, &wrapped) { log.Printf("root cause for %s: %v", name, errors.Unwrap(err)) }
    return fmt.Errorf("addon %s: %w", name, err)
}

Prevention

When it happens

Trigger: RemapAddonManifest(addon, ...) where addLabels fails on any object: the object's metadata cannot be reparsed into metav1.ObjectMeta, or an addon.Selector key already exists on the object with a different value.

Common situations: A custom addon manifest whose objects already carry the addon.kops.k8s.io/name label or a selector label set to a different value; malformed YAML metadata blocks; user-modified channel manifests.

Related errors


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