{"record":{"id":"998fab0a003ff6cf","repo":"kubernetes/kops","slug":"rewriting-channels-manifest-w","errorCode":null,"errorMessage":"rewriting channels manifest: %w","messagePattern":"rewriting channels manifest: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/commands/toolbox_enroll.go","lineNumber":958,"sourceCode":"\t\t\t\treturn nil, fmt.Errorf(\"parsing configStore.base %q: %w\", cluster.Spec.ConfigStore.Base, err)\n\t\t\t}\n\t\t\tbootstrapChannelURL := configBase.Join(\"addons\", \"bootstrap-channel.yaml\").Path()\n\n\t\t\taddonsPath := configBase.Join(\"addons\").Path()\n\t\t\tif err := remapTree(&addonsPath, path.Join(targetDir, \"addons\")); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tlocalAddons := addonsPath // remapTree mutated it in place to the on-host destination\n\t\t\tif err := remapFile(&nodeupConfig.ChannelsManifest, targetDir); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\trewritten, err := rewriteChannelsManifestForEnroll(\n\t\t\t\tbootstrapData.NodeupScriptAdditionalFiles[nodeupConfig.ChannelsManifest],\n\t\t\t\tbootstrapChannelURL,\n\t\t\t\tlocalAddons,\n\t\t\t)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"rewriting channels manifest: %w\", err)\n\t\t\t}\n\t\t\tbootstrapData.NodeupScriptAdditionalFiles[nodeupConfig.ChannelsManifest] = rewritten\n\t\t}\n\n\t\tif nodeupConfig.ConfigStore != nil {\n\t\t\tif err := remapTree(&nodeupConfig.ConfigStore.Keypairs, path.Join(targetDir, \"pki/etcd\")); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tif err := remapTree(&nodeupConfig.ConfigStore.Secrets, path.Join(targetDir, \"pki\")); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\n\t\tnodeupConfigBytes, err := yaml.Marshal(nodeupConfig)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error converting nodeup config to yaml: %w\", err)\n\t\t}\n\t\t// Not much reason to hash this, since we're reading it from the local file system","sourceCodeStart":940,"sourceCodeEnd":976,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/commands/toolbox_enroll.go#L940-L976","documentation":"After downloading the kops-channels static pod manifest and remapping the addons tree locally, kops rewrites the manifest so the container's bootstrap-channel URL arg points at the local file:// copy. rewriteChannelsManifestForEnroll returns an error (e.g. the manifest bytes could not be parsed as a Pod, or re-serializing failed) and this wrapper annotates it.","triggerScenarios":"GetBootstrapData on a control-plane group with an s3:// ChannelsManifest, where the downloaded channels manifest (from NodeupScriptAdditionalFiles) fails yaml.Unmarshal into corev1.Pod (\"parsing kops-channels manifest\"), or k8scodecs.ToVersionedYaml fails during re-serialization — e.g. the object in the state store was overwritten with non-Pod YAML/JSON, is corrupt, or was written by an incompatible kops version.","commonSituations":"Someone edited or replaced the s3 addons/kops-channels manifest with arbitrary YAML; partial/corrupted upload truncated the manifest; state store holds a manifest from a much older kops whose Pod spec doesn't decode into the vendored corev1 type; KMS/network corruption during read.","solutions":["Download the manifest from s3://<base>/addons/ and inspect it — restore a valid kops-channels Pod manifest (re-run `kops update cluster --yes` / upgrade to regenerate it).","Verify the file parses as a Kubernetes Pod (kubectl apply --dry-run=server or yamllint + kind: Pod check).","If corrupted during transfer, re-run the command after fixing connectivity/KMS permissions.","Align kops CLI version with the cluster version that wrote the manifest, then retry."],"exampleFix":"// before: hand-edited manifest in the state store\n$ kubectl get -f kops-channels.yaml\nerror: unable to recognize ... no kind registered\n// after: regenerate the manifest\nkops update cluster <name> --yes && kops toolbox enroll ...","handlingStrategy":"validation","validationCode":"// Before enroll: verify the channels manifest in the state store is a valid Pod YAML\naws s3 cp s3://<bucket>/<cluster>/addons/channels/... - | \\\n  yq -e '.kind == \"Pod\" and .spec.containers' >/dev/null && echo OK","typeGuard":"func isChannelsPod(manifest []byte) bool {\n    var pod corev1.Pod\n    return yaml.Unmarshal(manifest, &pod) == nil && pod.Kind == \"Pod\"\n}","tryCatchPattern":"if err := runToolboxEnroll(ctx, ...); err != nil {\n    if strings.Contains(err.Error(), \"rewriting channels manifest\") ||\n       strings.Contains(err.Error(), \"parsing kops-channels manifest\") {\n        // regenerate the manifest from a good source, then retry once\n        exec.Command(\"kops\", \"update\", \"cluster\", clusterName, \"--yes\").Run()\n        return runToolboxEnroll(ctx, ...)\n    }\n    return err\n}","preventionTips":["Don't hand-edit the kops-channels manifest in the state store; regenerate with `kops update cluster`.","Keep the kops CLI version aligned with the cluster version that produced the manifest.","After any manual s3 upload to addons/, dry-run parse it as a Pod before enrolling."],"tags":["go","yaml","kubernetes","manifest","enrollment"],"backgroundTag":"manifest-parse-failed","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}