kubernetes/kops · error
unable to find resource for %s: %w
Error message
unable to find resource for %s: %w
What it means
pruneObjectsOfKind asks the DeferredDiscoveryRESTMapper to map a GroupKind to a REST resource. If the discovery mapper has no mapping (kind unknown to the cluster), the error is wrapped as `unable to find resource for <gk>` and pruning of that kind aborts.
Source
Thrown at channels/pkg/channels/prune.go:83
}
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)
}
}
return nil
}
func (p *Pruner) pruneObjectsOfKind(ctx context.Context, gk schema.GroupKind, spec *api.PruneKindSpec, keepObjects []*kubemanifest.Object) error {
klog.Infof("pruning objects of kind: %v", gk)
restMapping, err := p.RESTMapper.RESTMapping(gk)
if err != nil {
return fmt.Errorf("unable to find resource for %s: %w", gk, err)
}
gvr := restMapping.Resource
var listOptions v1.ListOptions
listOptions.LabelSelector = spec.LabelSelector
listOptions.FieldSelector = spec.FieldSelector
baseResource := p.Client.Resource(gvr)
if len(spec.Namespaces) == 0 {
objects, err := baseResource.List(ctx, listOptions)
if err != nil {
return fmt.Errorf("error listing objects: %w", err)
}
if err := p.pruneObjects(ctx, gvr, objects, keepObjects); err != nil {
return err
}
} else {View on GitHub (pinned to 4c8573c808)
Solutions
- Check the kind exists: `kubectl api-resources | grep <kind>` and align the PruneSpec with actual group/kind
- Install the CRD before running the channel update/prune
- Reset the discovery cache (restart the controller/kops process) if a CRD was just installed
- Remove obsolete kinds from the PruneSpec for clusters where the API no longer exists
Example fix
// before kinds: - group: monitoring.coreos.com kind: ServiceMonitor # CRD not installed yet // after // apply the CRD first, or: kinds: - group: apps kind: Deployment
Defensive patterns
Strategy: validation
Validate before calling
gk := schema.GroupKind{Group: "monitoring.coreos.com", Kind: "ServiceMonitor"}
if _, err := restMapper.RESTMapping(gk); err != nil {
return fmt.Errorf("skip prune, kind %v unavailable in cluster", gk)
} Try / catch
if err := pruner.Prune(ctx, manifest, spec); err != nil {
if strings.Contains(err.Error(), "unable to find resource for") {
klog.Warningf("prune kind unknown to cluster, skipping: %v", err)
return nil // or install the CRD and retry
}
return err
} Prevention
- Cross-check prune spec kinds against `kubectl api-resources` for every supported cluster version
- Apply CRDs before addon manifests and pruning
- Bump/remove prune entries when a Kubernetes upgrade removes an API
- Restart processes after CRD installation if using a cached discovery mapper
When it happens
Trigger: The PruneSpec lists a kind whose resource does not exist on the API server: wrong group/kind, CRD not installed, API removed in the cluster's Kubernetes version, or discovery cache is stale.
Common situations: Typo'd kind in prune spec; pruning a custom resource before its CRD is applied; cluster upgraded to a version that removed an API (e.g. policy/v1beta1 kinds); discovery cache stale after CRD install.
Related errors
- error getting rest mapping for %v: %w
- error querying kubernetes version: %v
- cannot parse kubernetes version %q
- unknown scope for gvk %s: %q
- failed to create host %s/%s: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/213249d4beea3efc.
Report an issue: GitHub.