kubernetes/kops · error

Failed to annotate %T

Error message

Failed to annotate %T

What it means

addLabels reparses each manifest object's metadata into metav1.ObjectMeta to stamp kops ownership labels. If that reparse fails (metadata missing or not a valid ObjectMeta), the error is returned — but note it does not include the underlying parse error, only the Go type of the object, which makes diagnosing slightly harder.

Source

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

		if err := iam.AddServiceAccountRole(&context.IAMModelContext, podSpec, subject); err != nil {
			return err
		}

		if err := object.Set(podSpec, "spec", "template", "spec"); err != nil {
			return fmt.Errorf("failed to set object: %w", err)
		}

	}
	return nil
}

func addLabels(addon *addonsapi.AddonSpec, objects kubemanifest.ObjectList) error {
	for _, object := range objects {
		meta := &metav1.ObjectMeta{}
		err := object.Reparse(meta, "metadata")
		if err != nil {
			return fmt.Errorf("Failed to annotate %T", object)
		}

		if meta.Labels == nil {
			meta.Labels = make(map[string]string)
		}

		meta.Labels["app.kubernetes.io/managed-by"] = "kops"
		meta.Labels[KopsAddonLabelKey] = *addon.Name

		// ensure selector is set where applicable
		for key, val := range addon.Selector {
			existingVal, ok := meta.Labels[key]
			if ok && existingVal != val {
				return fmt.Errorf("label %q already set to %q while it should be %q", key, meta.Labels[key], val)
			}

			meta.Labels[key] = val
		}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Check the object type named in the error (%T) and fix its metadata block to be a valid ObjectMeta
  2. Validate the manifest YAML with kubectl --dry-run=client
  3. Remove unknown fields from metadata
  4. Restore the stock addon manifest from the matching channel

Example fix

# before (malformed)
metadata: kops-owned
# after
metadata:
  name: dns-controller
  namespace: kube-system
Defensive patterns

Strategy: validation

Validate before calling

// Pre-validate each object's metadata parses as ObjectMeta:
meta := &metav1.ObjectMeta{}
if err := object.Reparse(meta, "metadata"); err != nil {
    return fmt.Errorf("object %s/%s has invalid metadata: %v", object.Kind(), object.GetNamespace(), err)
}

Type guard

func hasValidMetadata(obj *kubemanifest.Object) bool {
    var meta metav1.ObjectMeta
    return obj.Reparse(&meta, "metadata") == nil
}

Try / catch

if err := addLabels(addon, objects); err != nil {
    if strings.HasPrefix(err.Error(), "Failed to annotate") {
        // err lacks root cause; re-run Reparse per object to surface the real decode error
        for _, obj := range objects {
            var meta metav1.ObjectMeta
            if rerr := obj.Reparse(&meta, "metadata"); rerr != nil { return fmt.Errorf("%v: %v", err, rerr) }
        }
    }
    return err
}

Prevention

When it happens

Trigger: addLabels iteration where object.Reparse(meta, "metadata") fails on any object in the addon manifest: metadata block malformed, wrong type (e.g. metadata is a string), or unknown fields rejected under strict parsing.

Common situations: Hand-crafted addon YAML with typos in the metadata block; objects with empty/invalid metadata; manifests generated by other tools with non-standard metadata fields the strict decoder rejects.

Related errors


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