How to convert kubernetes yaml to json
- Step 1Copy the manifest YAML — Paste a single Kubernetes resource or drop a
.yaml,.yml, or.txtfile onto the dropzone. The converter accepts anykind— Deployment, Service, ConfigMap, Ingress, or a CustomResourceDefinition — because it parses generic YAML, not a fixed Kubernetes schema. - Step 2Turn on Multi-document YAML if the file has `---` separators — This is the step most people miss. With the toggle off the parser uses
yaml.load, which throwsexpected a single document in the stream, but found moreon the second---. Turn the Multi-document YAML (---) checkbox on and each document is parsed into one array element. - Step 3Pick an indent — Minified emits a single-line body (smallest payload for an API call). 2 spaces or 4 spaces produce a pretty-printed object for reading or committing alongside the YAML.
- Step 4Convert and review the structure — Click Convert to JSON. For a single resource, confirm
apiVersion,kind,metadata, andspecsit at the top level. For a multi-doc file, confirm the array length equals your document count — a trailing---adds anullelement you may need to drop. - Step 5Check type coercion on numeric-looking fields — js-yaml coerces unquoted scalars:
port: 08becomes8,version: 1.20becomes1.2. If a field must stay a string (an image tag, a quoted port), make sure it is quoted in the source YAML before converting. - Step 6Use the JSON in your tooling — Pipe it to
kubectl apply -f -, load it as an Unstructured object in client-go, or validate required fields likespec.selectorfirst with the JSON Validator before applying to a cluster.
Converter options for Kubernetes manifests
The two controls in the UI and what each does for a k8s workflow. There are no other options — no schema validation, no apiVersion rewriting.
| Control | Values | What it does | Default |
|---|---|---|---|
| Multi-document YAML (---) | checkbox on / off | Off → yaml.load (single document; throws on a second ---). On → yaml.loadAll: one document yields an object, two or more yield a JSON array | Off |
| Indent | Minified · 2 spaces · 4 spaces | Output spacing. Minified is one line; 2/4 are pretty-printed. No effect on values, only formatting | 2 spaces |
| File input | .yaml .yml .txt | Drop or paste. Mime types application/x-yaml, text/yaml, text/plain are accepted | — |
How js-yaml coerces common Kubernetes scalars
js-yaml 4.1.1 uses the YAML 1.2 core schema. Unquoted scalars are typed automatically — this is where manifest values change shape.
| YAML in manifest | JSON out | Why it matters |
|---|---|---|
replicas: 3 | 3 (number) | Correct — k8s expects an integer here |
containerPort: 08 | 8 (number) | Leading zero dropped; harmless for ports but surprising in a diff |
version: "1.20" | "1.20" (string) | Quoted → preserved. Unquoted 1.20 becomes 1.2 |
image: nginx:1.21 | "nginx:1.21" | Stays a string — the colon does not break it |
enabled: true | true (boolean) | Real boolean. Note yes/no/on/off stay strings in YAML 1.2 |
value: (empty) / value: ~ | null | Empty scalars and ~ both become JSON null |
Cookbook
Real manifest snippets and the exact JSON the converter produces. The recurring theme: turn the multi-doc toggle on for stacks, and quote anything that must stay a string.
A single Deployment to JSON
ExampleThe base case: one resource, multi-doc toggle off, 2-space indent. apiVersion, kind, metadata, and spec land at the top level exactly as the API expects.
Input (deployment.yaml):
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
labels:
app: web
spec:
replicas: 3
selector:
matchLabels:
app: web
Output JSON (2-space):
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": { "name": "web", "labels": { "app": "web" } },
"spec": { "replicas": 3, "selector": { "matchLabels": { "app": "web" } } }
}A Deployment + Service stack with the multi-doc toggle ON
ExampleA real kubectl apply -f file with two documents. Toggle off, this throws. Toggle ON, you get a two-element array — one object per document.
Input (stack.yaml):
apiVersion: apps/v1
kind: Deployment
metadata: { name: web }
---
apiVersion: v1
kind: Service
metadata: { name: web-svc }
Multi-document YAML (---): ON
Output JSON:
[
{ "apiVersion": "apps/v1", "kind": "Deployment", "metadata": { "name": "web" } },
{ "apiVersion": "v1", "kind": "Service", "metadata": { "name": "web-svc" } }
]The single-document-stream error (toggle left OFF)
ExampleThe most common support question for this tool. The fix is one checkbox, not a different file.
Input: a 3-resource manifest with two `---` separators Multi-document YAML (---): OFF Error shown in the red panel: expected a single document in the stream, but found more Fix: turn the Multi-document YAML (---) checkbox on, re-run.
Quoted port stays a string; unquoted version loses a zero
ExampleTwo coercion traps in one manifest. Quote what must be text; expect numeric trimming on what you leave unquoted.
Input:
spec:
nodePort: "30080"
minorVersion: 1.10
Output JSON:
{
"spec": {
"nodePort": "30080", // quoted → string preserved
"minorVersion": 1.1 // unquoted 1.10 → 1.1
}
}Anchors and merge keys are expanded inline
ExampleHand-written manifests sometimes share a resources block via an anchor. The converter dereferences it — the JSON has no anchors left, just the expanded values.
Input:
resources: &res
limits: { cpu: "500m", memory: 256Mi }
containerA:
resources:
<<: *res
requests: { cpu: "100m" }
Output JSON (anchor resolved):
{
"resources": { "limits": { "cpu": "500m", "memory": "256Mi" } },
"containerA": { "resources": {
"limits": { "cpu": "500m", "memory": "256Mi" },
"requests": { "cpu": "100m" }
} }
}Errors and edge cases
Real errors and silent failures sourced from each platform's own documentation. Match the wording to the row, fix what the row says to fix.
Multi-document manifest with the toggle off
Parse errorWith Multi-document YAML (---) off, the parser calls yaml.load, which is strict about one document per stream and throws expected a single document in the stream, but found more at the first extra ---. This is not a malformed-file problem — turn the toggle on and re-run.
Trailing `---` after the last resource
Null elementA file ending in --- followed by nothing parses (with the toggle on) into an array whose final element is null. Harmless for inspection, but if you iterate the array to apply each resource, skip null elements. Remove the trailing separator in the source to avoid it.
CRD with a custom YAML tag like `!Custom`
Unknown tag errorPlain Kubernetes manifests have no custom tags, but if a value is annotated with an explicit unknown tag (!Custom, !Ref copied from CloudFormation, etc.) js-yaml throws unknown tag. The default schema only knows standard YAML 1.2 tags. Remove or quote the tagged value.
Tab character used for indentation
Tab errorYAML forbids tabs in indentation. A tab where spaces are expected throws tab characters must not be used in indentation, with line and column. Re-indent with spaces — most editors can convert tabs to spaces for .yaml files automatically.
Duplicate key inside one mapping
Duplicate key errorTwo metadata: blocks (or any repeated key) in the same mapping throw duplicated mapping key with the offending line. js-yaml rejects rather than silently keeping the last value — fix the manifest so each key appears once.
Empty or comments-only manifest
Undefined outputAn empty file (or one with only comments) parses to JS undefined, and the output is literally undefined rather than {} or null. Paste actual resource content. With the multi-doc toggle on, a single empty doc yields null.
`08` or `09` style numeric fields
By designLeading-zero integers like a containerPort: 08 are parsed as decimal 8 (js-yaml does not treat them as octal in the core schema). The value is numerically correct for k8s but the textual form changes — quote it if a literal "08" matters.
Quoted `"yes"`/`"no"` region or flag values
PreservedUnlike YAML 1.1 tools, js-yaml 4.x keeps yes/no/on/off as strings (no Norway problem), so a region: no stays "no" — not a boolean. If you actually want a boolean, write true/false.
Very large integer in a field (e.g. a generated ID)
Precision lossIntegers beyond JavaScript's safe range (2^53−1) lose precision through the JS number type — 9999999999999999999 round-trips as 10000000000000000000. Rare in k8s specs, but if you embed huge IDs, quote them so they stay exact strings.
File larger than the free 2 MB limit
Upgrade requiredFree tier caps JSON-family input at 2 MB and one file at a time — plenty for normal manifests. A monster generated manifest bundle over 2 MB needs Pro (100 MB). Or split the bundle and convert each resource separately.
Frequently asked questions
Why do I get `expected a single document in the stream`?
Your manifest has more than one document (two or more ----separated resources) and the Multi-document YAML (---) toggle is off, so the parser uses yaml.load, which allows only one document. Turn the toggle on — it switches to yaml.loadAll and converts each document into one array element.
Does turning on multi-doc always produce a JSON array?
No. With the toggle on, a file containing exactly one document still returns a single JSON object, not a one-element array. Only files with two or more documents produce an array. So the toggle is safe to leave on even for single-resource files.
Will the output work with `kubectl apply -f -`?
Yes. The JSON mirrors the Kubernetes object model, and kubectl apply -f - accepts JSON on stdin. For a multi-document array you would apply each element, or keep the original YAML for kubectl and use the JSON for inspection and fixtures.
Are YAML anchors and merge keys resolved?
Yes. js-yaml dereferences anchors (&name / *name) and merge keys (<<: *name) during parsing, so the JSON output has them fully expanded inline with no aliases remaining. Useful for hand-written manifests that share a resources or env block.
Why did my `containerPort: 08` become `8`?
js-yaml parses unquoted numeric scalars as numbers, dropping the leading zero. The value is still 8, which is correct for a port, but the textual form changed. Quote it ("08") in the source YAML if you need the literal preserved.
Why did `version: 1.20` become `1.2`?
Unquoted 1.20 is a float, and trailing zeros are not significant in a number — it serializes as 1.2. Version-like values should always be quoted in YAML ("1.20") so they stay strings; then they survive conversion exactly.
Can it validate the manifest against the Kubernetes schema?
No — this tool only converts YAML to JSON; it does not check required fields or apiVersion validity. After converting, paste the JSON into the JSON Validator for structural checks, or run it through a dedicated k8s schema validator before applying.
Is my Secret data uploaded anywhere?
No. Parsing runs entirely in your browser with js-yaml. Secret stringData, image-pull credentials, internal service names, and every other value stay on your machine — nothing is transmitted to JAD Apps servers.
What happens to a CRD with a custom `!`-tag?
Standard manifests have no custom tags, but if a value carries an explicit unknown tag the parser throws unknown tag. js-yaml's default schema only recognises standard YAML 1.2 tags. Remove or quote the tagged value before converting.
How do I convert YAML the other direction, JSON back to YAML?
Use the sibling JSON to YAML tool. It is the inverse converter and round-trips the structure produced here, which is handy if you generated a manifest as JSON and need it in YAML form for a Git repo.
How big a manifest can I convert on the free tier?
Free tier allows up to 2 MB of input and one file at a time, which covers essentially all hand-written manifests. Pro raises the limit to 100 MB and adds batch mode and API access for pipeline use.
Can I run this in a CI pipeline instead of the browser?
Pro unlocks API access for the JSON tools so you can drive the converter programmatically rather than pasting into the browser UI. A common pattern is to convert manifests to JSON in CI, then run JSONPath checks with the JSON Path Extractor to assert required labels are present.
Privacy first
Conversion runs locally in your browser. No file is uploaded — only metadata counters are saved for signed-in dashboard stats.