derailed/k9s · error
unsupported resource for scaling: %s
Error message
unsupported resource for scaling: %s
What it means
scaleRes (internal/dao/dp.go:394-396) supports exactly two GVRs - client.DpGVR (Deployments) and client.StsGVR (StatefulSets). Any other GVR that reaches this generic helper falls through the switch's default and is rejected with this message printing the GVR.
Source
Thrown at internal/dao/dp.go:394
switch gvr {
case client.DpGVR:
scale, e := dial.AppsV1().Deployments(ns).GetScale(ctx, n, metav1.GetOptions{})
if e != nil {
return e
}
scale.Spec.Replicas = replicas
_, e = dial.AppsV1().Deployments(ns).UpdateScale(ctx, n, scale, metav1.UpdateOptions{})
return e
case client.StsGVR:
scale, e := dial.AppsV1().StatefulSets(ns).GetScale(ctx, n, metav1.GetOptions{})
if e != nil {
return e
}
scale.Spec.Replicas = replicas
_, e = dial.AppsV1().StatefulSets(ns).UpdateScale(ctx, n, scale, metav1.UpdateOptions{})
return e
default:
return fmt.Errorf("unsupported resource for scaling: %s", gvr)
}
}
func restartRes[T runtime.Object](ctx context.Context, f Factory, gvr *client.GVR, path string, opts *metav1.PatchOptions) error {
o, err := f.Get(gvr, path, true, labels.Everything())
if err != nil {
return err
}
var r = new(T)
err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, r)
if err != nil {
return err
}
ns, n := client.Namespaced(path)
auth, err := f.Client().CanI(ns, gvr, n, client.PatchAccess)
if err != nil {
return errView on GitHub (pinned to 2d3ccc6ba2)
Solutions
- Scale only Deployments or StatefulSets through this path
- For other scalable kinds, use the resource-specific client (e.g. dial.AppsV1().ReplicaSets(ns).UpdateScale) or kubectl scale
- If you control the code, add a case for the GVR before the default branch
Example fix
// before
scaleRes(ctx, f, client.RsGVR, path, 3) // falls into default
// after
case client.RsGVR:
scale, e := dial.AppsV1().ReplicaSets(ns).GetScale(ctx, n, metav1.GetOptions{})
if e != nil { return e }
scale.Spec.Replicas = replicas
_, e = dial.AppsV1().ReplicaSets(ns).UpdateScale(ctx, n, scale, metav1.UpdateOptions{})
return e Defensive patterns
Strategy: type-guard
Validate before calling
// Reject unsupported GVRs before any authorization or API traffic.
func Scalable(gvr *client.GVR) bool {
return gvr == client.DpGVR || gvr == client.StsGVR
} Type guard
func ScaleTarget(gvr *client.GVR) (apply func(ctx context.Context, ns, name string, replicas int32) error, err error) {
switch gvr {
case client.DpGVR:
return applyDpScale, nil
case client.StsGVR:
return applyStsScale, nil
default:
return nil, fmt.Errorf("unsupported resource for scaling: %s", gvr)
}
} Try / catch
if !Scalable(gvr) { return fmt.Errorf("unsupported resource for scaling: %s", gvr) }
return scaleRes(ctx, f, gvr, path, replicas) Prevention
- Type-guard at the call site: never route ReplicaSets/CRDs into the shared scale helper
- When adding a scalable kind, extend the switch AND the RBAC pre-check list together
When it happens
Trigger: Routing a scale request for an unsupported kind through scaleRes - e.g. a Replicaset, ReplicationController, or a custom CRD with a scale subresource. Authorization (error 113) is checked before this switch, so you only see this error after RBAC passed.
Common situations: Extending k9s DAOs or writing plugins that call the scale path for other controllers; version drift where a caller assumed a GVR was added to the supported set.
Related errors
- user is not authorized to scale: %s
- failed to locate pod %q: %w
- user is not authorized to run jobs
- user is not authorized to (un)suspend cronjobs
- no valid selector found on deployment: %s
AI-assisted analysis of derailed/k9s@2d3ccc6ba2 (2026-08-15).
Data as JSON: /api/errors/df79182a01dcc730.
Report an issue: GitHub.