kubernetes/kops · error

parsing kops-channels manifest: %w

Error message

parsing kops-channels manifest: %w

What it means

When SELinux is enabled in the instance group's containerdConfig, nodeup must decorate the channels manifest, so it unmarshals the manifest bytes into a v1.Pod with sigs.k8s.io/yaml. If the stored manifest is not valid YAML or does not decode into a Pod object, the parse fails and is wrapped with this message.

Source

Thrown at nodeup/pkg/model/channels.go:105

func (b *ChannelsBuilder) readChannelsManifest(c *fi.NodeupModelBuilderContext) ([]byte, error) {
	ctx := c.Context()
	p, err := vfs.Context.BuildVfsPath(b.NodeupConfig.ChannelsManifest)
	if err != nil {
		return nil, fmt.Errorf("parsing path for kops-channels manifest %s: %w", b.NodeupConfig.ChannelsManifest, err)
	}
	data, err := p.ReadFile(ctx)
	if err != nil {
		return nil, fmt.Errorf("reading kops-channels manifest %s: %w", b.NodeupConfig.ChannelsManifest, err)
	}

	// SELinux is per-IG via containerdConfig, so the decoration can only be applied at nodeup.
	// Skip the parse/reserialize round-trip when there's nothing to add.
	if b.NodeupConfig.ContainerdConfig == nil || !b.NodeupConfig.ContainerdConfig.SeLinuxEnabled {
		return data, nil
	}
	pod := &v1.Pod{}
	if err := yaml.Unmarshal(data, pod); err != nil {
		return nil, fmt.Errorf("parsing kops-channels manifest: %w", err)
	}
	kubemanifest.AddHostPathSELinuxContext(pod, b.NodeupConfig)
	out, err := k8scodecs.ToVersionedYaml(pod)
	if err != nil {
		return nil, fmt.Errorf("re-marshaling kops-channels manifest: %w", err)
	}
	return out, nil
}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Re-run 'kops update cluster --yes' to regenerate and upload a fresh, valid kops-channels manifest.
  2. Inspect the manifest at the ChannelsManifest path and confirm it is a valid Pod YAML (kind: Pod) and not truncated.
  3. Ensure nodeup and kopsctl versions match; version-skewed manifests can fail schema decode.
  4. If not actually needing SELinux decoration, disable containerdConfig.seLinuxEnabled to skip the parse entirely.

Example fix

// before: truncated manifest uploaded
// after: regenerate
// kops update cluster mycluster --yes && systemctl restart nodeup
Defensive patterns

Strategy: validation

Validate before calling

var probe interface{}
if err := yaml.Unmarshal(manifestBytes, &probe); err != nil {
	return fmt.Errorf("channels manifest is not valid YAML before nodeup: %w", err)
}

Try / catch

if err := nodeupRun(ctx); err != nil && strings.Contains(err.Error(), "parsing kops-channels manifest") {
	// regenerate the manifest in the state store, then retry
	if err := kopsUpdateCluster(ctx); err != nil { return err }
	return nodeupRun(ctx)
}

Prevention

When it happens

Trigger: Build() on a master node with NodeupConfig.ContainerdConfig.SeLinuxEnabled=true and the channels manifest bytes are corrupt, empty, truncated, or not a Pod manifest (wrong kind or incompatible apiVersion fields).

Common situations: Partially uploaded/truncated manifest in the state store; an older or hand-modified kops-channels manifest that doesn't match the v1.Pod schema; binary corruption in the storage backend.

Related errors


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