derailed/k9s · error
expecting Service resource
Error message
expecting Service resource
What it means
StatefulSet.getStatefulSet converts the fetched unstructured object to appsv1.StatefulSet; on failure it returns 'expecting Service resource'. The message is a copy-paste from the Service DAO: the code is StatefulSet-specific and only the text is wrong. Semantics are identical to the StatefulSet conversion failure: the object's shape did not match appsv1.StatefulSet.
Source
Thrown at internal/dao/sts.go:109
func (s *StatefulSet) Pod(fqn string) (string, error) {
sts, err := s.getStatefulSet(fqn)
if err != nil {
return "", err
}
return podFromSelector(s.Factory, sts.Namespace, sts.Spec.Selector.MatchLabels)
}
func (s *StatefulSet) getStatefulSet(fqn string) (*appsv1.StatefulSet, error) {
o, err := s.getFactory().Get(s.gvr, 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 Service resource")
}
return &sts, nil
}
// ScanSA scans for serviceaccount refs.
func (s *StatefulSet) ScanSA(_ context.Context, fqn string, wait bool) (Refs, error) {
ns, n := client.Namespaced(fqn)
oo, err := s.getFactory().List(s.gvr, ns, wait, labels.Everything())
if err != nil {
return nil, err
}
refs := make(Refs, 0, len(oo))
for _, o := range oo {
var sts appsv1.StatefulSet
err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &sts)
if err != nil {View on GitHub (pinned to 2d3ccc6ba2)
Solutions
- Treat it as a StatefulSet conversion failure (the message text is wrong); verify the GVR passed to Init is client.StsGVR.
- Confirm apiVersion apps/v1 and a valid StatefulSet payload via kubectl get sts -o yaml.
- Correct the message locally or wrap the underlying conversion error to avoid the misleading text.
Example fix
// before (misleading copy-paste in internal/dao/sts.go getStatefulSet)
if err != nil { return nil, errors.New("expecting Service resource") }
// after
if err != nil { return nil, fmt.Errorf("expecting StatefulSet resource: %w", err) } Defensive patterns
Strategy: type-guard
Validate before calling
if s.gvr != client.StsGVR.String() { // guard DAO misuse
return nil, fmt.Errorf("statefulset DAO initialized with wrong gvr: %s", s.gvr)
} Type guard
func isStatefulSet(o runtime.Object) bool {
u, ok := o.(*unstructured.Unstructured)
return ok && u.GetKind() == "StatefulSet"
} Prevention
- Remember the 'Service' wording is a copy-paste bug; diagnose as StatefulSet conversion.
- Always Init the DAO with client.StsGVR.
- Validate apiVersion apps/v1 before conversion.
When it happens
Trigger: The object returned by s.getFactory().Get(s.gvr, fqn, ...) is not convertible to appsv1.StatefulSet — s.gvr misconfigured (pointing at a non-sts resource), apiVersion drift, or webhook-mutated fields that the typed converter rejects.
Common situations: Initializing the DAO with a GVR other than client.StsGVR; cluster/apiVersion upgrades; debugging confused by the wrong 'Service' wording pointing devs at the Service code path.
Related errors
- expecting Statefulset resource
- expecting Service resource
- expected Unstructured, but got %T
- expecting cronjob resource
- expecting Deployment resource
AI-assisted analysis of derailed/k9s@2d3ccc6ba2 (2026-08-15).
Data as JSON: /api/errors/ae83736f0a519130.
Report an issue: GitHub.