{"record":{"id":"022b40edd5fd0b31","repo":"kubernetes/kops","slug":"error-applying-annotation-to-record-addon-installa","errorCode":null,"errorMessage":"error applying annotation to record addon installation: %v","messagePattern":"error applying annotation to record addon installation: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"channels/pkg/channels/addon.go","lineNumber":232,"sourceCode":"\t\t\tmerr = multierr.Append(merr, fmt.Errorf(\"error applying update after prune: %w\", err))\n\t\t} else {\n\t\t\t// If we succeeded to apply after prune, clear the errors\n\t\t\tmerr = nil\n\t\t}\n\t}\n\n\tif merr != nil {\n\t\treturn fmt.Errorf(\"error updating addon from %q: %w\", manifestURL, merr)\n\t}\n\n\tif err := a.AddNeedsUpdateLabel(ctx, k8sClient, required); err != nil {\n\t\treturn fmt.Errorf(\"error adding needs-update label: %v\", err)\n\t}\n\n\tchannel := a.buildChannel()\n\terr = channel.SetInstalledVersion(ctx, k8sClient, a.ChannelVersion())\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error applying annotation to record addon installation: %v\", err)\n\t}\n\treturn nil\n}\n\nfunc (a *Addon) AddNeedsUpdateLabel(ctx context.Context, k8sClient kubernetes.Interface, required *AddonUpdate) error {\n\tif required.ExistingVersion != nil {\n\t\tif a.Spec.NeedsRollingUpdate != \"\" {\n\t\t\terr := a.patchNeedsUpdateLabel(ctx, k8sClient)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"error patching needs-update label: %v\", err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (a *Addon) patchNeedsUpdateLabel(ctx context.Context, k8sClient kubernetes.Interface) error {\n\tklog.Infof(\"addon %v wants to update %v nodes\", a.Name, a.Spec.NeedsRollingUpdate)","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/channels/pkg/channels/addon.go#L214-L250","documentation":"updateAddon wraps failures from Channel.SetInstalledVersion, which records the installed addon version as an annotation (addons.k8s.io/<name>) on the target namespace. The addon manifest was applied, but the installed-version annotation could not be written, so subsequent runs will consider the addon out-of-date and re-apply it.","triggerScenarios":"EnsureUpdated -> updateAddon calls SetInstalledVersion after a successful apply; failure occurs when the namespace Get fails (namespace missing/not ready, RBAC), ChannelVersion.Encode() fails, or the namespace strategic-merge Patch fails (RBAC, conflict, API server error).","commonSituations":"kops applying addons before target namespaces exist; service account lacking patch permission on namespaces; 'kops update cluster' racing with namespace deletion; kubeconfig pointing at the wrong cluster.","solutions":["Ensure the target namespace exists and the caller's RBAC allows get/patch on namespaces.","Re-run the apply; recording the version is retried automatically next run since the recorded hash won't match.","Check cluster API server health and the kubeconfig context.","Clear stale addons.k8s.io/* annotations on the namespace if corrupted, then re-apply."],"exampleFix":"// before\nerr = channel.SetInstalledVersion(ctx, k8sClient, a.ChannelVersion())\nif err != nil {\n\treturn fmt.Errorf(\"error applying annotation to record addon installation: %v\", err)\n}\n// after\nif err := channel.SetInstalledVersion(ctx, k8sClient, a.ChannelVersion()); err != nil {\n\treturn fmt.Errorf(\"error applying annotation to record addon installation for %q: %w\", a.Name, err)\n}","handlingStrategy":"retry","validationCode":"_, err := k8sClient.CoreV1().Namespaces().Get(ctx, \"kube-system\", metav1.GetOptions{})\nif err != nil {\n\treturn fmt.Errorf(\"namespace not accessible, version annotation will fail: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := updateAddon(...); err != nil {\n\tif strings.Contains(err.Error(), \"error applying annotation to record addon installation\") {\n\t\t// idempotent: re-running will re-record the version annotation\n\t\tretryWithBackoff(3, func() error { return updateAddon(...) })\n\t}\n}","preventionTips":["Pre-create required namespaces before applying addons.","Grant namespace get/patch RBAC to the operator identity.","Verify kubeconfig points at the intended cluster.","Avoid deleting namespaces while kops update runs."],"tags":["kubernetes","annotations","rbac","namespaces"],"backgroundTag":"addon-version-annotation-write-failed","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}