kubernetes/kops · error

expected exactly one container in etcd-manager Pod, found %d

Error message

expected exactly one container in etcd-manager Pod, found %d

What it means

buildPod assumes the etcd-manager Pod template contains exactly one container, whose settings it then mutates (image override, ports, env). If the parsed Pod has zero or multiple containers, the builder cannot know which to configure and fails.

Source

Thrown at pkg/model/components/etcdmanager/model.go:295

	for _, etcdVersion := range etcdVersions {
		if etcdVersion.SymlinkToVersion == "" {
			volume := v1.Volume{
				Name: "etcd-v" + strings.ReplaceAll(etcdVersion.Version, ".", "-"),
				VolumeSource: v1.VolumeSource{
					Image: &v1.ImageVolumeSource{
						Reference:  b.AssetBuilder.RemapImage(etcdVersion.Image),
						PullPolicy: v1.PullIfNotPresent,
					},
				},
			}
			pod.Spec.Volumes = append(pod.Spec.Volumes, volume)
		}
	}

	{
		if len(pod.Spec.Containers) != 1 {
			return nil, fmt.Errorf("expected exactly one container in etcd-manager Pod, found %d", len(pod.Spec.Containers))
		}
		container = &pod.Spec.Containers[0]

		if etcdCluster.Manager != nil && etcdCluster.Manager.Image != "" {
			klog.Warningf("overloading image in manifest %s with images %s", bundle, etcdCluster.Manager.Image)
			container.Image = etcdCluster.Manager.Image
		}

		// Remap image via AssetBuilder
		container.Image = b.AssetBuilder.RemapImage(container.Image)

		for _, etcdVersion := range etcdVersions {
			volumeMount := v1.VolumeMount{
				MountPath: "/opt/etcd-v" + etcdVersion.Version,
			}
			if etcdVersion.SymlinkToVersion == "" {
				volumeMount.Name = "etcd-v" + strings.ReplaceAll(etcdVersion.Version, ".", "-")
			} else {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Keep exactly one container in the etcd-manager Pod manifest; move sidecars into a separate Pod or static manifest.
  2. Restore the vendored template and re-apply only supported overrides (etcdCluster.Manager.image).
  3. If a sidecar is essential, run it as a separate DaemonSet/standalone Pod rather than editing this template.

Example fix

// before
containers:
- name: etcd-manager
  ...
- name: log-sidecar
  ...
// after
containers:
- name: etcd-manager
  ...
Defensive patterns

Strategy: validation

Validate before calling

if len(pod.Spec.Containers) != 1 {
	return fmt.Errorf("etcd-manager manifest must have exactly one container, found %d", len(pod.Spec.Containers))
}

Prevention

When it happens

Trigger: buildManifest -> buildPod with a customized etcd-manager Pod manifest listing 0 or 2+ entries under spec.containers (e.g. a added sidecar container).

Common situations: Users adding sidecars (log shippers, monitors) to the etcd-manager Pod template; stripping containers during templating; merge tooling duplicating the container entry.

Related errors


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