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
- Inspect the rendered YAML (skaffold deploy --helm-render or `helm template`) and fix the chart manifest with the bad apiVersion/kind or malformed YAML.
- Ensure the chart's resources use apiVersion/kind pairs supported by the Kubernetes scheme (e.g. `apiVersion: v1, kind: List` wrapping needs splitting).
- Update skaffold if the resource is a newer builtin type your skaffold's k8s.io libs don't decode.
- 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
- Run `helm template` locally in CI to catch invalid rendered manifests before deploy
- Ensure every chart template emits both apiVersion and kind
- Keep skaffold/k8s.io library versions current with your chart's API versions
- Exclude non-manifest documents (NOTES, hooks) from rendered output
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
- invalid local-registry-hosting ConfigMap
- strings.Join(errMsgs, "\n") (joined helm cleanup error messa
- parsing manifests file into manifest list object: %w
- marshalling yaml: %w
- error converting %s to map[string]interface{}
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/03d9f56a654ec26c.
Report an issue: GitHub.