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

  1. Read the wrapped error (%w) first — it names the exact field/type that failed to decode
  2. Reproduce with kubectl get <resource> -o wide / -v=6 to see whether the table conversion fails server-side too
  3. For CRDs, validate instance payloads against the OpenAPI schema and fix offending fields (kubectl get <crd> -o yaml | kubectl validate-style checks)
  4. 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

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

Related errors


AI-assisted analysis of derailed/k9s@2d3ccc6ba2 (2026-08-15). Data as JSON: /api/errors/7ef98103d42d397a. Report an issue: GitHub.