YAML error
“error converting YAML to JSON”
kubectl does not parse YAML directly. It converts each document to JSON first, and this wrapper means that conversion failed because the YAML is malformed. The real error is the part after “yaml: line N:”, and N counts from the start of that document, not from the top of the file.
By yamltojsonfree · Published · Updated
What the parser is telling you
Kubernetes tools read a manifest with a decoder that splits the file at each ---, converts one document at a time to JSON with the sigs.k8s.io/yaml library, and only then maps the JSON onto a Deployment or a Service. A syntax error stops the first step, so you get “error converting YAML to JSON” followed by go-yaml’s message. Nothing about your Kubernetes object has been checked yet.
Because each document is converted on its own, the line number is relative to the document. In a file with a Service followed by a Deployment, an error on the Deployment’s eleventh line is reported as line 10, not as line 19. Helm adds a second offset: it reports lines in the rendered template, which can differ from the source once include, range and toYaml have expanded.
Two other kubectl messages look similar but mean different things. “error validating data” means the YAML parsed and the object failed schema validation, for example an unknown field. “error unmarshaling JSON” or “cannot unmarshal string into Go struct field” means the YAML parsed but a value has the wrong type, such as replicas: "3" with quotes.
Who prints this message
kubectl, Helm, kustomize and every tool built on the Kubernetes YAML libraries print this wrapper. The text after “yaml: line N:” comes from go-yaml and is the actual error.
The causes, with fixes
Broken YAML on the left, the corrected form on the right. The fix under each pair is the one that applies to that cause.
Find the document, then the line
The manifest below fails on file line 19, the eleventh line of the second document, but kubectl reports yaml: line 10: did not find expected '-' indicator: image sits one space left of name, so it belongs neither to the list item nor to the list.
Broken
apiVersion: v1
kind: Service
metadata:
name: api
spec:
ports:
- port: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
spec:
replicas: 1
template:
spec:
containers:
- name: api
image: nginxFixed
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
spec:
replicas: 1
template:
spec:
containers:
- name: api
image: nginxFix: Count lines from the first line after the previous ---, and expect the number to be off by one.
Read the inner message, then its own page
The text after “yaml: line N:” is one of a handful of go-yaml messages, each explained on this site: mapping values are not allowed in this context for a colon inside a value or a line indented too deep; did not find expected key for a key at a column that belongs to no block, or a dash where a key was expected; could not find expected ':' for a line without a colon; found character that cannot start any token for a tab used as indentation; control characters are not allowed for escape codes in the file; and did not find expected '-' indicator for a key wedged between a list’s dash and its items, as above.
Broken
# what kubectl prints
error: error parsing deploy.yaml:
error converting YAML to JSON:
yaml: line 10: did not find expected keyFixed
# how to read it
# file: deploy.yaml
# document: the one after the last ---
# line: 10 or 11 of that document
# problem: did not find expected keyFix: This pair is the message and its reading, not YAML to convert.
Helm: the line is in the rendered output
A template that renders to an empty value, or an include without nindent, produces YAML that is only wrong after rendering.
Broken
env:
{{- include "app.env" . }}Fixed
env:
{{- include "app.env" . | nindent 2 }}Fix: Run helm template . --debug to see the rendered manifest and count lines there. helm lint catches most of these before install.
Find it fast
- 1.Reproduce without touching the cluster:
kubectl apply --dry-run=client -f file.yaml. - 2.Split the file at
---and find the document with the reported line; the number counts from the line after the separator and may be one lower than you count. - 3.Paste that document into the YAML validator on this site. It reads the whole input, marks the exact line and, for unclosed brackets and quotes, names the line where the delimiter was opened.
- 4.Once the YAML parses, an “error validating data” message is about the object’s fields, not its syntax; check the field names with
kubectl explain.
How the message reads in each tool
| Parser | Message |
|---|---|
| kubectl, kustomize | error: error parsing file.yaml: error converting YAML to JSON: yaml: line N: ... |
| Helm | Error: YAML parse error on chart/templates/x.yaml: error converting YAML to JSON: yaml: line N: ... |
| kubectl, schema stage | error validating data: ValidationError(Deployment.spec): unknown field ... |
| kubectl, type stage | error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string into Go struct field ... |
Frequently asked questions
kubectl says line 12, but line 12 of my file is fine. Why?
kubectl splits the file at each --- and converts one document at a time, so the number is relative to the document that failed, not the file. Count from the first line after the previous separator. The number is also often one lower than the line you would count in an editor, so check that line and the one below it.
Is “error converting YAML to JSON” a Kubernetes problem or a YAML problem?
A YAML problem. The conversion happens before kubectl looks at what kind of object the file describes, so the manifest has a syntax error and would fail in any YAML parser. Problems with field names appear as “error validating data”, and wrong value types appear as “cannot unmarshal”.
Why does Helm report a line that does not exist in my template?
Helm parses the rendered output, not the template source. Lines added or removed by include, range, toYaml or an expression that renders empty shift the numbering. Use helm template with --debug to see the rendered YAML and find the line there, then trace it back to the template.
Related errors
“did not find expected key”
The parser was inside a mapping and expected either another key at the same indentation or the end of the block, but found something that cannot be a key: a line dedented by the wrong amount, a list dash, or an invisible character. Line up the indentation of the line it reports with its siblings.
Read the fix“mapping values are not allowed in this context”
The parser hit a colon followed by a space in the middle of a value, where YAML only allows a colon after a key. Quote the value if the colon is part of it, or fix the line above if the parser was still reading it.
Read the fix“could not find expected ':'”
A line that sits where a key belongs has no colon on it. Usually the colon is missing or has no space after it, or a long value wrapped onto a new line without quotes. Add the colon, or quote or block-format the value.
Read the fix“control characters are not allowed”
The file contains a byte that YAML forbids anywhere in a document: a control character such as a terminal escape code, a form feed, a NUL byte or DEL. The usual source is coloured command output redirected into a file. Find the byte with grep and delete it.
Read the fixAll six underlying mistakes, ordered by cause rather than by message, are in the guide Common YAML errors and how to fix them. Every one of them is caught with the exact line and a suggested fix by the free tools below; nothing is uploaded.
YAML to JSON
Convert YAML into formatted or minified JSON, with errors pinned to the exact line.
OpenJSON to YAML
Turn JSON back into readable YAML, with control over indentation and key order.
OpenYAML Validator
Check YAML for syntax errors and get a plain-English explanation of what went wrong.
OpenYAML Formatter
Reformat messy YAML with consistent indentation and keep your comments intact.
Open