Convert YAML to JSON (and Avoid Indentation Errors)

Since YAML 1.2 every JSON document is valid YAML. Convert YAML config to JSON, and watch for indentation and type-inference traps.

YAML and JSON Are Related

YAML 1.2 is a strict superset of RFC 8259 JSON — every valid JSON document is also valid YAML. Converting YAML to JSON mainly means turning indentation-based structure into braces and brackets, plus quoting any scalars whose meaning could change.

Paste a YAML payload into the YAML to JSON converter to apply the rules below in one pass.

A Concrete Example

YAML on the left, the equivalent JSON on the right of the conversion. Same data, two surfaces:

# YAML
name: Ada Lovelace
active: true
skills:
  - math
  - notes
profile:
  city: London
  year: 1815
{
  "name": "Ada Lovelace",
  "active": true,
  "skills": ["math", "notes"],
  "profile": { "city": "London", "year": 1815 }
}

The indentation became braces and brackets; the comment was dropped (JSON has no comments); everything else maps one-to-one.

Indentation Rules

YAML forbids tab characters for indentation — use spaces, and keep sibling keys at the same depth. A stray tab or a misaligned key is the most common YAML parse error. The amount of indentation isn't fixed (2 spaces is conventional, but any consistent count works); what matters is that siblings line up exactly.

The Norway Problem

Unquoted NO, yes, on, and off are read as booleans by YAML 1.1 parsers — so the ISO country code for Norway becomes false. YAML 1.2 narrowed the boolean set to just true / false, but many production parsers (including some versions of PyYAML and Ruby's Psych) still default to 1.1 semantics. The safe fix is to quote any string that could be misread:

# Broken — every "NO" becomes the boolean false
country_codes: [NO, FI, SE, DK]

# Fixed — explicit strings
country_codes: ["NO", "FI", "SE", "DK"]

The same trap catches version numbers (2.0 becoming a float, losing the trailing zero), leading-zero numbers (007 becoming 7), and date-like strings (2026-06-20 becoming a date object). When in doubt, quote.

Multi-Document YAML Streams

A single YAML file can hold multiple documents separated by ---. JSON has no equivalent — convert each document independently and wrap them in a JSON array if a downstream tool needs all of them in one value:

# YAML — three Kubernetes resources in one file
apiVersion: v1
kind: ConfigMap
metadata: { name: app-config }
---
apiVersion: v1
kind: Service
metadata: { name: app-svc }
---
apiVersion: apps/v1
kind: Deployment
metadata: { name: app }
[
  { "apiVersion": "v1", "kind": "ConfigMap", "metadata": { "name": "app-config" } },
  { "apiVersion": "v1", "kind": "Service", "metadata": { "name": "app-svc" } },
  { "apiVersion": "apps/v1", "kind": "Deployment", "metadata": { "name": "app" } }
]

Kubernetes manifests are the most common case; many kubectl workflows assume the array wrapper above when the multi-document stream needs to flow through a JSON-only tool.

Anchors and Aliases

YAML's & anchor and * alias let you reuse a node by reference. JSON has no aliases — a safe converter resolves each alias to a copy of the anchored value, which expands the document:

# YAML — single source of truth, referenced twice
defaults: &timeouts
  connect: 5
  read: 30
services:
  api: { <<: *timeouts, port: 8080 }
  worker: { <<: *timeouts, port: 9090 }
{
  "defaults": { "connect": 5, "read": 30 },
  "services": {
    "api": { "connect": 5, "read": 30, "port": 8080 },
    "worker": { "connect": 5, "read": 30, "port": 9090 }
  }
}

Round-tripping back to YAML loses the original sharing — the converter has no way to know that "these two identical sub-trees should be one alias" without a hint.

When YAML Loses Fidelity

Several YAML features are not representable in JSON and are dropped during conversion:

YAML feature What happens in JSON
Comments (# …) Dropped — JSON has no comments
Tag annotations (!!binary, !!set, custom tags) Dropped — JSON has only the six core types
Block vs flow style distinction Collapsed — JSON has only flow style ({...}, [...])
Key order (when the parser preserves it) May be lost depending on the JSON consumer
Anchor sharing (& / *) Expanded into duplicated subtrees

For pure data interchange that's fine; for human-edited config that gets edited again later, keep the YAML as the source of truth.

Common YAML Parsers

The conversion behavior depends on which parser produces the YAML on disk. The widely-used ones, all worth knowing the quirks of:

  • JavaScript / TypeScriptjs-yaml (YAML 1.2, the default for most tooling)
  • PythonPyYAML (defaults to YAML 1.1 unless safe_load is paired with explicit options) and ruamel.yaml (1.2-strict, preserves comments)
  • Gogopkg.in/yaml.v3 (YAML 1.2)
  • Ruby — Psych (the stdlib parser; YAML 1.1 by default)

If your producer and your consumer use different YAML versions, expect Norway-problem-class surprises.

See also

This guide handles one format boundary. The hub lists every JSON ↔ neighbor-format conversion with its standard and edge cases.

Sources

Last reviewed June 2026.