derailed/k9s · error
expecting a scalable resource for %q
Error message
expecting a scalable resource for %q
What it means
ScaleExtender.scale (internal/view/scale_extender.go:225) resolves the DAO for the GVR and asserts dao.Scalable (Scale(ctx, path, replicas)). If the accessor does not implement Scale, scaling is refused. In practice only DAOs for resources exposing the Kubernetes scale subresource implement it.
Source
Thrown at internal/view/scale_extender.go:225
SetBackgroundColorActivated(styles.ButtonFocusBgColor.Color()).
SetLabelColorActivated(styles.ButtonFocusFgColor.Color())
}
return f, nil
}
func (s *ScaleExtender) dismissDialog() {
s.App().Content.RemovePage(scaleDialogKey)
}
func (s *ScaleExtender) scale(ctx context.Context, path string, replicas int32) error {
res, err := dao.AccessorFor(s.App().factory, s.GVR())
if err != nil {
return err
}
scaler, ok := res.(dao.Scalable)
if !ok {
return fmt.Errorf("expecting a scalable resource for %q", s.GVR())
}
return scaler.Scale(ctx, path, replicas)
}
View on GitHub (pinned to 2d3ccc6ba2)
Solutions
- Verify the resource actually supports scaling (deployments, replicasets, statefulsets do)
- For a CRD, add the scale subresource to the CRD spec (subresources.scale with statusReplicasPath / specReplicasPath / labelSelectorPath) so its DAO can implement Scale
- Scale via kubectl to confirm server-side support: 'kubectl scale --replicas=N <gvr>/<name>'; if the server rejects it, the resource is not scalable at all
- Remove the scale keybinding from non-scalable views
Example fix
# before: CRD without scale subresource -> expecting a scalable resource for "mycrds.example.com"
# after: add to CRD spec
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
spec:
versions:
- name: v1
subresources:
scale:
specReplicasPath: .spec.replicas
statusReplicasPath: .status.replicas
labelSelectorPath: .status.labelSelector Defensive patterns
Strategy: type-guard
Validate before calling
// capability check before scaling
res, err := dao.AccessorFor(s.App().factory, s.GVR())
if err != nil { return err }
if _, ok := res.(dao.Scalable); !ok {
return fmt.Errorf("%s does not support scale; add a scale subresource or use kubectl", s.GVR())
} Type guard
func isScalable(res dao.Resource) (dao.Scalable, bool) {
sc, ok := res.(dao.Scalable)
return sc, ok
} Prevention
- Ensure CRDs define subresources.scale so their DAOs can implement dao.Scalable
- Bind the scale key only on deploy/rs/sts viewers
- Compile-time assert: var _ dao.Scalable = (*MyDAO)(nil)
When it happens
Trigger: Pressing the scale keybinding on a GVR whose DAO lacks Scale — custom CRDs without a scale subresource, or a generic accessor registered for an alias.
Common situations: Trying to scale CRDs (operators) that do not define `subresources: [scale]` in their CRD spec; k9s forks attaching ScaleExtender broadly; interface drift after upgrades.
Related errors
- user is not authorized to scale: %s
- unsupported resource for scaling: %s
- failed to decode table rows: %w
- strings.Join(errs, " - ")
- node is cordoned
AI-assisted analysis of derailed/k9s@2d3ccc6ba2 (2026-08-15).
Data as JSON: /api/errors/d59bf7c1fb751755.
Report an issue: GitHub.