derailed/k9s · error

unable to marshal resource %w

Error message

unable to marshal resource %w

What it means

Generic.ToYAML (internal/dao/generic.go:92-106) fetches a resource and serializes it (dao.ToYAML) for the YAML view. If serialization of the fetched object fails, this error wraps the marshal error (note: the format string omits a colon, so the message reads "unable to marshal resource <err>").

Source

Thrown at internal/dao/generic.go:104

	return dial.Namespace(ns).Get(ctx, n, opts)
}

// Describe describes a resource.
func (g *Generic) Describe(path string) (string, error) {
	return Describe(g.Client(), g.gvr, path)
}

// ToYAML returns a resource yaml.
func (g *Generic) ToYAML(path string, showManaged bool) (string, error) {
	o, err := g.Get(context.Background(), path)
	if err != nil {
		return "", err
	}

	raw, err := ToYAML(o, showManaged)
	if err != nil {
		return "", fmt.Errorf("unable to marshal resource %w", err)
	}
	return raw, nil
}

// Delete deletes a resource.
func (g *Generic) Delete(ctx context.Context, path string, propagation *metav1.DeletionPropagation, grace Grace) error {
	ns, n := client.Namespaced(path)
	auth, err := g.Client().CanI(ns, g.gvr, n, []string{client.DeleteVerb})
	if err != nil {
		return err
	}
	if !auth {
		return fmt.Errorf("user is not authorized to delete %s", path)
	}

	var gracePeriod *int64
	if grace != DefaultGrace {
		gracePeriod = (*int64)(&grace)

View on GitHub (pinned to 2d3ccc6ba2)

Solutions

  1. Retry the view with managed fields hidden (toggle y) - stripping managedFields sometimes removes the offending payload
  2. Inspect the resource with kubectl get <res> <name> -o yaml to spot NaN/Infinity values
  3. Report/fix the operator writing non-finite numbers; represent them as strings ("Infinity") as Prometheus configs do
  4. As a last resort read the object via kubectl, since kubectl's JSON-path output tolerates these values
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-scan an unstructured object for values yaml cannot encode (NaN/Inf).
func YamlSafe(u *unstructured.Unstructured) error {
	var walk func(v any) error
	walk = func(v any) error {
		switch t := v.(type) {
		case float64:
			if math.IsNaN(t) || math.IsInf(t, 0) { return fmt.Errorf("non-finite number %v in %s", t, u.GetName()) }
		case map[string]any:
			for _, x := range t { if err := walk(x); err != nil { return err } }
		case []any:
			for _, x := range t { if err := walk(x); err != nil { return err } }
		}
		return nil
	}
	return walk(u.Object)
}

Try / catch

raw, err := g.ToYAML(path, showManaged)
if err != nil && strings.Contains(err.Error(), "unable to marshal resource") {
    // degrade gracefully: dump JSON instead, which tolerates these values
    raw, err = json.MarshalIndent(o.Object, "", "  ")
}
if err != nil { return "", err }

Prevention

When it happens

Trigger: The unstructured object contains values go-yaml cannot encode: NaN/+Inf/-Inf float values (common in metrics CRDs like ServiceMonitor or PrometheusRule objects and status fields), unsupported map key types, or huge/malformed annotations - data that survived JSON decoding but fails YAML marshaling.

Common situations: Viewing YAML of monitoring CRDs whose threshold fields legitimately hold Infinity; resources with exotic annotation payloads written by operators; k9s showManaged toggling which strips/keeps managed fields during marshal.

Related errors


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