derailed/k9s · error
failed to decode table rows: %w
Error message
failed to decode table rows: %w
What it means
Table.List hydrates a metav1.Table by decoding each row in a worker pool (pool.Drain collects per-row errors) and reports only the first failure, wrapped as 'failed to decode table rows: %w'. The underlying cause is whatever the row decoder returned, typically a type-conversion failure on row cells or contained objects.
Source
Thrown at internal/dao/table.go:137
}
row.Object.Object = converted
var m metav1.Object
if obj := row.Object.Object; obj != nil {
m, _ = meta.Accessor(obj)
}
var ns string
if m != nil {
ns = m.GetNamespace()
}
if namespaced {
row.Cells = append([]any{ns}, row.Cells...)
}
return nil
})
}
errs := pool.Drain()
if len(errs) > 0 {
return nil, fmt.Errorf("failed to decode table rows: %w", errs[0])
}
return table, nil
}
func (t *Table) getClient(f serializer.CodecFactory) (*rest.RESTClient, error) {
cfg, err := t.Client().RestConfig()
if err != nil {
return nil, err
}
gv := t.gvr.GV()
cfg.GroupVersion = &gv
cfg.APIPath = "/apis"
if t.gvr.G() == "" {
cfg.APIPath = "/api"
}
cfg.NegotiatedSerializer = f.WithoutConversion()
crRestClient, err := rest.RESTClientFor(cfg)View on GitHub (pinned to 2d3ccc6ba2)
Solutions
- Read the wrapped error (%w) first — it names the exact field/type that failed to decode
- Reproduce with kubectl get <resource> -o wide / -v=6 to see whether the table conversion fails server-side too
- For CRDs, validate instance payloads against the OpenAPI schema and fix offending fields (kubectl get <crd> -o yaml | kubectl validate-style checks)
- Report or update the operator/extension API server if its schema serializes values the table decoder cannot convert
Defensive patterns
Strategy: try-catch
Try / catch
rows, err := table.List(ctx)
if err != nil {
if strings.HasPrefix(err.Error(), "failed to decode table rows") {
// the wrapped cause names the offending field; log it fully and degrade to raw list
slog.Error("table decode failed", slogs.Error, errors.Unwrap(err))
return listRawWithoutTableConversion(ctx) // e.g. Accept: application/json
}
return err
} Prevention
- Always log the wrapped error (%w) — the outer message alone says nothing actionable
- Keep CRD schemas strict (typed fields) so table row conversion cannot fail
- Smoke-test list views for every CRD after operator upgrades
When it happens
Trigger: Listing a resource in table format where one or more rows fail conversion: custom resources (CRDs) whose status/spec fields don't round-trip through unstructured conversion, aggregated APIServer resources with non-standard cell types, or rows referencing objects the user can partially get but whose embedded objects decode with errors.
Common situations: Third-party operators with loosely typed CRD schemas (float in int fields, nested maps); mixed-privilege namespaces where partial RBAC yields odd table rows; version skew between an extension API server and its CRD schema.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- unable to find data section in secret description
- data section in secret description is invalid
- no table found for gvr: %s
- no data found for resource %s
- expecting a scalable resource for %q
AI-assisted analysis of derailed/k9s@2d3ccc6ba2 (2026-08-15).
Data as JSON: /api/errors/7ef98103d42d397a.
Report an issue: GitHub.