kubernetes/kops · error
expected Pod object in manifest %s, found %T
Error message
expected Pod object in manifest %s, found %T
What it means
After the single-object check, buildHealthcheckSidecar type-asserts the parsed object to *corev1.Pod. If the sole object in the sidecar bundle manifest is not a Pod (e.g. a Deployment or ConfigMap), the assertion fails and this error reports the actual Go type via %T. It protects the subsequent code that directly manipulates pod.Spec fields.
Source
Thrown at pkg/model/components/kubeapiserver/model.go:130
// 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
- Restore the official sidecar bundle (kind: Pod) by using an unmodified official kOps build
- Change the bundle's YAML document kind to Pod if maintaining a custom bundle
- Check git history of the assets/bundle directory for accidental replacements
- Report upstream if official release reproduces
Example fix
// before (bundle manifest) apiVersion: apps/v1 kind: Deployment // after apiVersion: v1 kind: Pod
Defensive patterns
Strategy: type-guard
Validate before calling
// Pre-check bundle kind before model build
objects, err := model.ParseManifest(bundleBytes)
if err != nil {
return err
}
if len(objects) == 1 {
if _, ok := objects[0].(*corev1.Pod); !ok {
return fmt.Errorf("bundle must define a Pod, got %T", objects[0])
}
} Type guard
// Narrow the parsed manifest object to a Pod
func asPod(obj runtime.Object) (*corev1.Pod, bool) {
p, ok := obj.(*corev1.Pod)
return p, ok
} Try / catch
if err := buildManifest(); err != nil {
if strings.Contains(err.Error(), "expected Pod object in manifest") {
return fmt.Errorf("sidecar bundle kind wrong — restore kind: Pod: %w", err)
}
return err
} Prevention
- Ensure custom sidecar bundles declare kind: Pod
- Diff custom bundles against upstream templates
- Test bundle parsing in CI for forked kOps builds
When it happens
Trigger: kops update cluster with a healthcheck sidecar bundle whose single YAML document defines a non-Pod kind — due to an edited/corrupted embedded bundle or a kOps build packaging the wrong file.
Common situations: Custom kOps builds where the sidecar bundle was accidentally replaced, or assets regenerated with the wrong template kind.
Related errors
- expected exactly one object in manifest %s, found %d
- expected exactly one container in etcd-manager Pod, found %d
- unexpected kind for cluster, got %T, want kops.Cluster
- unexpected object type: %T
- error reading certificate %q: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/ab12fae75d6a7065.
Report an issue: GitHub.