GoogleContainerTools/skaffold · error
reading Kubernetes YAML: %w
Error message
reading Kubernetes YAML: %w
What it means
ManifestList.Visit unmarshals each manifest document into map[string]interface{} with yaml.Unmarshal before applying a FieldVisitor. Malformed or non-mapping YAML (invalid syntax, tabs, documents that are lists/scalars) fails unmarshalling and is wrapped as 'reading Kubernetes YAML', aborting the whole visit.
Source
Thrown at pkg/skaffold/kubernetes/manifest/visitor.go:222
Labels: []string{".spec.template.metadata.labels"},
},
}
// FieldVisitor represents the aggregation/transformation that should be performed on each traversed field.
type FieldVisitor interface {
// Visit is called for each transformable key contained in the object and may apply transformations/aggregations on it.
// It should return true to allow recursive traversal or false when the entry was transformed.
Visit(gk apimachinery.GroupKind, navpath string, object map[string]interface{}, key string, value interface{}, rs ResourceSelector) bool
}
// Visit recursively visits all transformable object fields within the manifests and lets the visitor apply transformations/aggregations on them.
func (l *ManifestList) Visit(visitor FieldVisitor, rs ResourceSelector) (ManifestList, error) {
var updated ManifestList
for _, manifest := range *l {
m := make(map[string]interface{})
if err := yaml.Unmarshal(manifest, &m); err != nil {
return nil, fmt.Errorf("reading Kubernetes YAML: %w", err)
}
if len(m) == 0 {
continue
}
traverseManifestFields(m, visitor, rs)
updatedManifest, err := yaml.Marshal(m)
if err != nil {
return nil, fmt.Errorf("marshalling yaml: %w", err)
}
updated = append(updated, updatedManifest)
}
return updated, nil
}View on GitHub (pinned to a1189de023)
Solutions
- Validate each manifest with a YAML parser or `kubectl apply --dry-run=client` to find the broken document
- Fix the syntax error (tabs, unquoted special chars, unrendered templates) in the offending manifest
- Ensure every document in the manifest list is a single YAML mapping (not a top-level array); render templates fully before passing to Skaffold
Example fix
# before (tabs / template placeholder)
metadata:
name: {{ .Name }}
# after
metadata:
name: my-app # rendered value, spaces for indentation Defensive patterns
Strategy: validation
Validate before calling
doc := make(map[string]interface{})
if err := yaml.Unmarshal(manifestBytes, &doc); err != nil {
return fmt.Errorf("invalid manifest YAML: %w", err)
}
if len(doc) == 0 {
return nil // skip empty document before Visit
} Type guard
func isYAMLMap(b []byte) bool {
var m map[string]interface{}
return yaml.Unmarshal(b, &m) == nil && len(m) > 0
} Try / catch
updated, err := manifests.Visit(visitor, rs)
if err != nil && strings.Contains(err.Error(), "reading Kubernetes YAML") {
// locate offending document, validate with yamllint, then retry
return err
} Prevention
- Run yamllint/kubeconform on all rendered manifests before visiting
- Fully render Helm/kustomize templates — no leftover {{ }} placeholders
- Use spaces, never tabs, for YAML indentation
- Ensure each document root is a mapping, not a list or scalar
When it happens
Trigger: Calling Visit (via SetLabels, GetImages, replaceImages, SetPlatformNodeAffinity, etc.) on a ManifestList containing syntactically invalid YAML, or YAML whose root is not a map (e.g. a top-level list), including multi-doc lists where one document is broken.
Common situations: Helm/kustomize output containing template placeholders ({{ }}) left unrendered; YAML with tabs instead of spaces; JSON/YAML merge errors; a LIST (kind: List) or raw string fed in where an object was expected.
Related errors
- parsing manifests file into manifest list object: %w
- invalid local-registry-hosting ConfigMap
- CONFIG_MISSING_MANIFEST_FILE_ERR
- rendering manifests: %w
- rendering manifests: %w
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/606cea3ad245c63f.
Report an issue: GitHub.