kubernetes/kops · error
error getting rest mapping for %v: %w
Error message
error getting rest mapping for %v: %w
What it means
UnstructuredClient.dynamicResource resolves a GroupVersionKind to a concrete resource via the RESTMapper before performing Patch/Update/Get. If the RESTMapper cannot find a mapping (resource not registered on the server, wrong GVK, or discovery failure), the error is wrapped as "error getting rest mapping for %v" including the GVK.
Source
Thrown at pkg/applylib/applyset/unstructuredclient.go:54
// restMapper is used to map object kind to resources, and to know if objects are cluster-scoped.
restMapper meta.RESTMapper
}
// NewUnstructuredClient constructs an UnstructuredClient
func NewUnstructuredClient(options Options) *UnstructuredClient {
return &UnstructuredClient{
client: options.Client,
restMapper: options.RESTMapper,
}
}
// dynamicResource is a helper to get the resource for a gvk (with the namespace)
// It returns an error if a namespace is provided for a cluster-scoped resource,
// or no namespace is provided for a namespace-scoped resource.
func (c *UnstructuredClient) dynamicResource(ctx context.Context, gvk schema.GroupVersionKind, ns string) (dynamic.ResourceInterface, error) {
restMapping, err := c.restMapper.RESTMapping(gvk.GroupKind(), gvk.Version)
if err != nil {
return nil, fmt.Errorf("error getting rest mapping for %v: %w", gvk, err)
}
gvr := restMapping.Resource
switch restMapping.Scope.Name() {
case meta.RESTScopeNameNamespace:
if ns == "" {
// TODO: Differentiate between server-fixable vs client-fixable errors?
return nil, fmt.Errorf("namespace was not provided for namespace-scoped object %v", gvk)
}
return c.client.Resource(gvr).Namespace(ns), nil
case meta.RESTScopeNameRoot:
if ns != "" {
// TODO: Differentiate between server-fixable vs client-fixable errors?
return nil, fmt.Errorf("namespace %q was provided for cluster-scoped object %v", ns, gvk)
}
return c.client.Resource(gvr), nil
View on GitHub (pinned to 4c8573c808)
Solutions
- Confirm the resource exists: `kubectl api-resources | grep <kind>` and check the exact group/version.
- Apply CRDs before the custom resources that use them (order the applyset, or run twice).
- Fix the apiVersion/kind in the manifest to match a registered GVK.
- Reset/refresh the discovery RESTMapper (recreate the client) after installing new CRDs to clear stale caches.
Example fix
// before apiVersion: apps/v1beta2 kind: Deployment // after apiVersion: apps/v1 kind: Deployment
Defensive patterns
Strategy: validation
Validate before calling
if _, err := restMapper.RESTMapping(gvk.GroupKind(), gvk.Version); err != nil {
return fmt.Errorf("resource %s not present on cluster: %w", gvk, err)
} Try / catch
if err := client.Patch(ctx, gvk, nn, types.ApplyPatchType, data, opts); err != nil {
var discoveryErr *meta.NoKindMatchError
if errors.As(err, &discoveryErr) {
return applyCRDsFirst(ctx) // install CRDs, then retry
}
return err
} Prevention
- Always apply CRDs before custom resources in the same pass.
- Validate apiVersion/kind against `kubectl api-resources` output.
- Refresh the discovery RESTMapper after installing new CRDs.
- Check API server /healthz and discovery endpoints when mappings fail cluster-wide.
When it happens
Trigger: Calling Patch/Update/Get with a GVK that has no registered REST mapping: the CRD doesn't exist yet, the apiVersion/kind in the manifest is misspelled, or the discovery cache is stale after a new CRD was installed.
Common situations: Applying a custom resource before its CRD in the same apply pass; typos like apps/v1 Deployment vs extensions/v1beta1; the API server's discovery endpoints unreachable so the mapper has no data; new CRD created moments ago and the cached mapper not invalidated.
Related errors
- unable to find resource for %s: %w
- error querying kubernetes version: %v
- cannot parse kubernetes version %q
- unknown scope for gvk %s: %q
- listing server preferred resources: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/5f93dd2c8079fb4d.
Report an issue: GitHub.