kubernetes/kops · error

failed to parse apiVersion %q

Error message

failed to parse apiVersion %q

What it means

Every object in the manifest must carry a parseable apiVersion with a non-empty version so it can be mapped to a GroupVersion. If schema.ParseGroupVersion fails (e.g. apiVersion contains more than one '/') or the version is empty, Prune returns this error naming the bad apiVersion.

Source

Thrown at channels/pkg/channels/prune.go:55

// Prune prunes objects not in the manifest, according to PruneSpec.
func (p *Pruner) Prune(ctx context.Context, manifest []byte, spec *api.PruneSpec) error {
	klog.Infof("Prune spec: %v", spec)

	if spec == nil {
		return nil
	}

	objects, err := kubemanifest.LoadObjectsFrom(manifest)
	if err != nil {
		return fmt.Errorf("failed to parse objects: %w", err)
	}

	objectsByKind := make(map[schema.GroupKind][]*kubemanifest.Object)
	for _, object := range objects {
		gv, err := schema.ParseGroupVersion(object.APIVersion())
		if err != nil || gv.Version == "" {
			return fmt.Errorf("failed to parse apiVersion %q", object.APIVersion())
		}
		kind := object.Kind()
		if kind == "" {
			return fmt.Errorf("failed to find kind in object")
		}

		gvk := gv.WithKind(kind)
		gk := gvk.GroupKind()
		objectsByKind[gk] = append(objectsByKind[gk], object)
	}

	for i := range spec.Kinds {
		pruneKind := &spec.Kinds[i]
		gk := schema.GroupKind{Group: pruneKind.Group, Kind: pruneKind.Kind}
		if err := p.pruneObjectsOfKind(ctx, gk, pruneKind, objectsByKind[gk]); err != nil {
			return fmt.Errorf("failed to prune objects of kind %s: %w", gk, err)
		}
	}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Set a valid apiVersion (`<group>/<version>`, or `v1` for core) on every document in the manifest
  2. Validate with `kubectl apply --dry-run=client -f manifest.yaml` which reports missing/malformed apiVersions
  3. Check the specific document named by the %q value in the error

Example fix

// before
kind: Deployment
metadata:
  name: web
// after
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
Defensive patterns

Strategy: validation

Validate before calling

func checkAPIVersions(manifest []byte) error {
    objs, _ := kubemanifest.LoadObjectsFrom(manifest)
    for _, o := range objs {
        gv, err := schema.ParseGroupVersion(o.APIVersion())
        if err != nil || gv.Version == "" {
            return fmt.Errorf("bad apiVersion %q", o.APIVersion())
        }
    }
    return nil
}

Try / catch

if err := pruner.Prune(ctx, manifest, spec); err != nil {
    var bad string
    if n, _ := fmt.Sscanf(err.Error(), "failed to parse apiVersion %q", &bad); n == 1 {
        return fmt.Errorf("fix apiVersion %q in manifest", bad)
    }
    return err
}

Prevention

When it happens

Trigger: A manifest document has `apiVersion: ""`, a missing apiVersion, or a malformed value like `apiVersion: apps/v1/extra`, or only a group with no version (`apiVersion: apps`).

Common situations: Hand-edited addon manifests omitting apiVersion; custom resource documents copied from docs using wrong apiVersion strings; generator output missing apiVersion on some documents.

Understand the failure class

Related errors


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