kubernetes/kops · error

expected exactly one object in manifest %s, found %d

Error message

expected exactly one object in manifest %s, found %d

What it means

buildHealthcheckSidecar loads the bundled etcd-manager healthcheck sidecar manifest (from the embedded bundle file) and parses it with model.ParseManifest, then asserts it contains exactly one object. If the parsed manifest holds a different number of objects, it returns this error naming the bundle path. This validates the integrity of the asset baked into the kOps binary.

Source

Thrown at pkg/model/components/kubeapiserver/model.go:127

      type: Directory
`

// buildHealthcheckSidecar builds the partial pod for the healthcheck sidecar.
// nodeup will merge it into the kube-apiserver pod.
func (b *KubeApiserverBuilder) buildHealthcheckSidecar() (*corev1.Pod, error) {
	// TODO: pull from bundle
	bundle := "(embedded kube-apiserver-healthcheck manifest)"
	manifest := []byte(fmt.Sprintf(defaultManifest, kopsversion.KopsVersionImageTag(), wellknownports.KubeAPIServerHealthCheck))

	var pod *corev1.Pod
	var container *corev1.Container
	{
		objects, err := model.ParseManifest(manifest)
		if err != nil {
			return nil, err
		}
		if len(objects) != 1 {
			return nil, fmt.Errorf("expected exactly one object in manifest %s, found %d", bundle, len(objects))
		}
		if podObject, ok := objects[0].(*corev1.Pod); !ok {
			return nil, fmt.Errorf("expected Pod object in manifest %s, found %T", bundle, objects[0])
		} else {
			pod = podObject
		}

		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]
	}

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

	return pod, nil
}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Rebuild/download an official kOps release so the embedded bundle matches expectations
  2. Inspect the bundle file at the path shown in the error and remove extra YAML documents
  3. Verify no build tooling rewrites files under the embedded assets directory
  4. File an upstream issue if it occurs on an official release

Example fix

// before: bundle contains Pod + Service
---
apiVersion: v1
kind: Pod
---
apiVersion: v1
kind: Service
// after: keep exactly one Pod document
apiVersion: v1
kind: Pod
Defensive patterns

Strategy: validation

Validate before calling

// Verify bundle integrity before invoking the model
objects, err := model.ParseManifest(bundleBytes)
if err != nil {
    return err
}
if len(objects) != 1 {
    return fmt.Errorf("sidecar bundle must contain exactly one object, got %d", len(objects))
}

Try / catch

pod, err := buildHealthcheckSidecar(ctx, b, bundle)
if err != nil {
    if strings.Contains(err.Error(), "expected exactly one object") {
        return fmt.Errorf("embedded sidecar bundle corrupted — reinstall official kOps: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: kops update cluster where the embedded healthcheck sidecar bundle file was corrupted, replaced, or contains multiple YAML documents — e.g. a broken kOps build or a modified assets bundle.

Common situations: Home-built or patched kOps binaries with edited bundle files, corrupted GO embed, or using a dev build whose bundle content drifted from expectations.

Related errors


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