GoogleContainerTools/skaffold · error

error decoding parsed yaml: %s

Error message

error decoding parsed yaml: %s

What it means

Skaffold's helm renderer parses rendered YAML and decodes each document into a Kubernetes runtime object via the universal deserializer. If the decoded bytes are not a valid, registered Kubernetes API object (bad apiVersion/kind, malformed manifest, or a non-manifest document like a plain ConfigMap-less YAML), decoding fails and this error wraps the deserializer's message.

Source

Thrown at pkg/skaffold/deploy/helm/parse.go:71

			continue
		}
		obj, err := parseRuntimeObject(objNamespace, doc)
		if err != nil {
			log.Entry(context.TODO()).Infof("error parsing object %d from string: %s", i, err.Error())
		} else {
			results = append(results, *obj)
			log.Entry(context.TODO()).Debugf("found deployed object %d: %+v", i, obj.Obj)
		}
	}

	return results
}

func parseRuntimeObject(namespace string, b []byte) (*types.Artifact, error) {
	d := scheme.Codecs.UniversalDeserializer()
	obj, _, err := d.Decode(b, nil, nil)
	if err != nil {
		return nil, fmt.Errorf("error decoding parsed yaml: %s", err.Error())
	}
	return &types.Artifact{
		Obj:       obj,
		Namespace: namespace,
	}, nil
}

func getObjectNamespaceIfDefined(doc []byte, ns string) (string, error) {
	if i := bytes.Index(doc, []byte("apiVersion")); i >= 0 {
		manifests := manifest.ManifestList{doc[i:]}
		namespaces, err := manifests.CollectNamespaces()
		if err != nil {
			return ns, err
		}
		if len(namespaces) > 0 {
			return namespaces[0], nil
		}
	}

View on GitHub (pinned to a1189de023)

Solutions

  1. Inspect the rendered YAML (skaffold deploy --helm-render or `helm template`) and fix the chart manifest with the bad apiVersion/kind or malformed YAML.
  2. Ensure the chart's resources use apiVersion/kind pairs supported by the Kubernetes scheme (e.g. `apiVersion: v1, kind: List` wrapping needs splitting).
  3. Update skaffold if the resource is a newer builtin type your skaffold's k8s.io libs don't decode.
  4. Filter out non-manifest documents (empty/notes) from the chart output via .helm_files or release config.

Example fix

// before: chart template emits invalid object
kind: {{ .Values.kind }}
// after: ensure apiVersion and kind are always rendered together
apiVersion: apps/v1
kind: {{ .Values.kind | default "Deployment" }}
Defensive patterns

Strategy: validation

Validate before calling

// Validate rendered YAML decodes as a K8s object before deploying
import "sigs.k8s.io/yaml"
var m map[string]interface{}
if err := yaml.Unmarshal(doc, &m); err != nil {
    return fmt.Errorf("invalid yaml: %w", err)
}
if m["apiVersion"] == nil || m["kind"] == nil {
    return fmt.Errorf("document missing apiVersion/kind: %v", m)
}

Prevention

When it happens

Trigger: A helm template output document that fails scheme.Codecs.UniversalDeserializer().Decode — e.g. helm chart emits YAML with an empty document, a kind/apiVersion the scheme doesn't know, or raw non-Kubernetes YAML (hooks output, NOTES-rendered files).

Common situations: Charts emitting CRDs or resources not in the typed scheme; charts with invalid templates producing malformed YAML; helm `--no-hooks` misconfigurations letting hook manifests through; API version drift between chart and installed Kubernetes scheme.

Related errors


AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05). Data as JSON: /api/errors/03d9f56a654ec26c. Report an issue: GitHub.