derailed/k9s · error
expecting Statefulset resource
Error message
expecting Statefulset resource
What it means
StatefulSet.GetInstance fetches the object via the factory and converts the unstructured payload into a typed appsv1.StatefulSet with runtime.DefaultUnstructuredConverter.FromUnstructured. If the returned object's shape does not satisfy the StatefulSet schema, the conversion error is replaced by this sentinel message. Typical root causes are an apiVersion mismatch (apps/v1 vs beta) or schema drift between the cached object and the compiled-in type.
Source
Thrown at internal/dao/sts.go:71
return scaleRes(ctx, s.getFactory(), client.StsGVR, path, replicas)
}
// Restart a StatefulSet rollout.
func (s *StatefulSet) Restart(ctx context.Context, path string, opts *metav1.PatchOptions) error {
return restartRes[*appsv1.StatefulSet](ctx, s.getFactory(), client.StsGVR, path, opts)
}
// GetInstance returns a statefulset instance.
func (*StatefulSet) GetInstance(f Factory, fqn string) (*appsv1.StatefulSet, error) {
o, err := f.Get(client.StsGVR, fqn, true, labels.Everything())
if err != nil {
return nil, err
}
var sts appsv1.StatefulSet
err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &sts)
if err != nil {
return nil, errors.New("expecting Statefulset resource")
}
return &sts, nil
}
// TailLogs tail logs for all pods represented by this StatefulSet.
func (s *StatefulSet) TailLogs(ctx context.Context, opts *LogOptions) ([]LogChan, error) {
sts, err := s.getStatefulSet(opts.Path)
if err != nil {
return nil, errors.New("expecting StatefulSet resource")
}
if sts.Spec.Selector == nil || len(sts.Spec.Selector.MatchLabels) == 0 {
return nil, fmt.Errorf("no valid selector found on statefulset: %s", opts.Path)
}
return podLogs(ctx, sts.Spec.Selector.MatchLabels, opts)
}
View on GitHub (pinned to 2d3ccc6ba2)
Solutions
- Check the object's apiVersion/kind first: it must be apps/v1 StatefulSet for the conversion to succeed.
- Refresh the cache (restart k9s / re-list) if the cluster was just upgraded or the CRD changed.
- Wrap the conversion with the underlying err (fmt.Errorf with %w) to see exactly which field failed instead of the generic message.
Example fix
// before
err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &sts)
if err != nil { return nil, errors.New("expecting Statefulset resource") }
// after
if err != nil { return nil, fmt.Errorf("expecting Statefulset resource: %w", err) } Defensive patterns
Strategy: type-guard
Validate before calling
u, ok := o.(*unstructured.Unstructured)
if !ok || u.GetKind() != "StatefulSet" || u.GetAPIVersion() != "apps/v1" {
return nil, fmt.Errorf("unexpected kind %s/%s", u.GetAPIVersion(), u.GetKind())
} Type guard
func isStatefulSet(o runtime.Object) bool {
u, ok := o.(*unstructured.Unstructured)
return ok && u.GetKind() == "StatefulSet" && u.GetAPIVersion() == "apps/v1"
} Try / catch
sts, err := stsDAO.GetInstance(f, fqn)
if err != nil {
if strings.Contains(err.Error(), "expecting Statefulset resource") {
// check apiVersion/schema drift or stale cache before retrying
}
return err
} Prevention
- Check apiVersion/kind before conversion.
- Keep k9s (and its k8s.io/api) aligned with the cluster version.
- Wrap conversion errors with %w to expose the failing field.
When it happens
Trigger: GetInstance called on an object served under a different apiVersion/kind than appsv1.StatefulSet (e.g. leftovers from apps/v1beta2 clusters, or a CRD shadowing the sts GVR); conversion of unknown/renamed fields fails.
Common situations: Clusters upgraded from old Kubernetes versions where statefulsets existed in beta apiGroups; aggregated APIs or mutating webhooks that inject fields the typed struct rejects; stale informer cache after a CRD/CR version change.
Related errors
- expecting Service resource
- expecting Service resource
- expecting cronjob resource
- expecting Deployment resource
- expecting DaemonSet resource
AI-assisted analysis of derailed/k9s@2d3ccc6ba2 (2026-08-15).
Data as JSON: /api/errors/15d3fcb413602cf5.
Report an issue: GitHub.