YAML to JSON: Convert Config Files to JSON Instantly
Free YAML to JSON converter — bidirectional, with exact line/column errors for indentation mistakes instead of a stack trace. Covers the Norway problem.
Try it now: YAML to JSON Converter — Convert YAML to JSON and JSON to YAML, reformat a config file, and get a line number for the indentation mistake instead of a stack trace.
Why YAML Took Over Config Files
YAML ("YAML Ain't Markup Language") is a data serialization format built around indentation and minimal punctuation, designed to represent the same nested maps, lists, and scalar values that JSON represents — just with a syntax meant to be written and read by a human first, and parsed by a machine second. That design goal is exactly why it became the default format for the configuration layer of modern software: Kubernetes manifests, GitHub Actions workflows, Docker Compose files, GitLab CI and CircleCI pipeline definitions, Ansible playbooks, and dozens of other tools all standardized on YAML rather than JSON or an INI-style format.
Two concrete properties explain that adoption, not vague appeal. First, YAML supports comments (anything after a # on a line) and JSON does not — at all, by design, per the JSON specification. For a config file that a human maintains, edits, and reviews in a pull request, the ability to write # TODO: remove this once the migration finishesnext to a setting is not a nice-to-have; it's the difference between a config file that explains itself and one that requires spelunking through git blame to understand. Second, YAML has dramatically less punctuation noise than JSON once nesting gets deep. A JSON object needs a curly brace to open, a comma after every key but the last, and a matching brace to close — multiplied across every nesting level. YAML expresses the same nesting with indentation alone, which is why a 40-line Kubernetes Deployment manifest in YAML reads as a outline of settings, while the equivalent JSON reads as a wall of braces and commas.
None of that means YAML is a different data model from JSON — it isn't. Both represent the same three building blocks: scalars (strings, numbers, booleans, null), sequences (lists), and mappings (key-value objects). A yaml to json converter is possible at all, cleanly and losslessly in the common case, precisely because the underlying structure the two formats describe is identical; only the surface syntax differs.
# Service configuration
service:
name: payments-api
port: 8443
replicas: 3
env:
- name: LOG_LEVEL
value: info
- name: FEATURE_FLAG_NEW_CHECKOUT
value: "true"
healthCheck:
path: /healthz
intervalSeconds: 10
tags:
- production
- payments
- tier-1{
"service": {
"name": "payments-api",
"port": 8443,
"replicas": 3,
"env": [
{ "name": "LOG_LEVEL", "value": "info" },
{ "name": "FEATURE_FLAG_NEW_CHECKOUT", "value": "true" }
],
"healthCheck": {
"path": "/healthz",
"intervalSeconds": 10
},
"tags": ["production", "payments", "tier-1"]
}
}Notice what disappeared in the conversion: every comment. That's not a bug in the converter — it's a direct consequence of JSON having no comment syntax at all, so there is nowhere in the JSON output for # Service configuration to go. Keep the annotated YAML as the source of truth for anything a human edits, and treat generated JSON as a build artifact for whatever needs to consume it.
Indentation Is Syntax, Not Style
This is the single most important thing to understand about YAML, and the single most common source of a confusing parse failure: indentation in YAML is syntactically significant, the same way it is in Python. Two spaces of indentation don't just make a block look nested — they are what makes it nested. That is a fundamentally different rule from JSON, where whitespace between tokens is purely cosmetic and can never change what a document means; you can compress a JSON file to a single line or reformat it with eight-space indentation and it parses to the exact same value either way. Do the same reformatting carelessly to a YAML file and you can silently change its meaning, or break it outright.
Two indentation mistakes account for the large majority of real-world YAML parse errors:
- Mixed tabs and spaces. The YAML specification disallows tab characters for indentation entirely — a document that indents with a literal tab where a space was expected is not ambiguous, it is invalid, full stop. This bites people constantly because most editors render a tab and a handful of spaces identically on screen, so the file looks correctly indented right up until a parser rejects it.
- Misaligned indentation by even one column.Because nesting depth is inferred purely from how many spaces precede a line, a key indented one space more or less than its siblings either attaches it to the wrong parent, or produces an outright syntax error if the misalignment doesn't line up with any valid nesting level at all.
service:
name: payments-api
env:
name: LOG_LEVEL
value: infoA generic parser hitting that file typically raises something like yaml.scanner.ScannerError: while scanning for the next token, found character '\t' that cannot start any token — a real message, but one that names the character, not the actual mistake in context. A good YAML tool goes one step further and reports the exact line and columnwhere the offending indentation sits — in this example, line 4, where a tab replaces the two leading spaces every sibling key uses — so the fix is immediate instead of a manual scan through the file counting spaces by eye. That's exactly the gap GenKitLab's YAML formatter closes: pinpoint the line and column of an indentation problem instead of surfacing a generic, unhelpful parser stack trace that never actually points at the mistake.
The Norway Problem: Unquoted Strings That Become Booleans
The "Norway problem" is a well-documented, real gotcha in YAML, not folklore. Under the parsing rules of YAML 1.1 — the version most widely-used parsers, including PyYAML's default loader and many others, still implement — certain bare, unquoted words are implicitly interpreted as booleans rather than left as plain strings. yes, no, on, off, and their case variants (Yes, NO, On, and so on) all fall into that set.
The name comes from the practical case that keeps surprising people: the ISO 3166-1 two-letter country code for Norway is NO. Write it unquoted as a YAML scalar — say, a list of country codes in a config file — and a YAML 1.1 parser reads it back not as the string "NO" but as the boolean false. The value silently changes type on the way through the parser, with no error raised anywhere, because as far as the parser is concerned it did exactly what the spec says to do with an unquoted NO token.
# Looks like a list of two-letter country codes... supported_countries: - US - NO - SE - FI
{
"supported_countries": ["US", false, "SE", "FI"]
}The practical lesson is simple and worth internalizing: quote any string value that could be misread as a boolean or a number. "NO", "yes", and even numeric-looking strings like version identifiers or zip codes with leading zeros deserve explicit quotes in YAML, precisely because the format's implicit typing rules will otherwise make a decision on your behalf that a JSON document never would — JSON has no unquoted-string-to-boolean coercion at all, since every JSON string is delimited by quotes unconditionally. Running a file through a yaml validator before it reaches production is the cheapest way to catch this kind of silent type coercion before it becomes a debugging session.
Anchors and Aliases: Reusing a Block Without Repeating It
Config files accumulate repetition fast — the same resource limits across five services, the same retry policy across a dozen jobs. YAML has a built-in mechanism for avoiding that duplication: anchors and aliases. An ampersand followed by a name (&anchor-name) marks a node — a scalar, a mapping, or a sequence — as reusable. An asterisk followed by that same name (*anchor-name) references it anywhere else in the document, and the parser substitutes the full anchored node in its place, as if it had been written out verbatim.
defaults: &default-resources
cpu: "500m"
memory: "512Mi"
services:
api:
resources: *default-resources
worker:
resources: *default-resources
scheduler:
resources:
<<: *default-resources
memory: "1Gi"{
"defaults": { "cpu": "500m", "memory": "512Mi" },
"services": {
"api": { "resources": { "cpu": "500m", "memory": "512Mi" } },
"worker": { "resources": { "cpu": "500m", "memory": "512Mi" } },
"scheduler": {
"resources": { "cpu": "500m", "memory": "1Gi" }
}
}
}The <<: *default-resources line under scheduleris the merge key extension — it merges the anchored mapping's keys into the current mapping, and any key defined locally afterward (here, memory: "1Gi") overrides the merged-in value. Converting a document that uses anchors to JSON always fully expands every alias, because JSON has no equivalent reference mechanism of its own — the output is larger and more repetitive than the YAML source, which is a normal, expected part of flattening the format, not a bug in the conversion.
Block Scalars: Literal (|) vs. Folded (>) Style
YAML has two dedicated styles for writing a multi-line string, and they don't just format differently — they produce genuinely different string content, which is why picking the wrong one is a real bug, not a cosmetic choice.
- Literal style (
|) preserves every line break in the block exactly as written. What you see indented under the|is what you get back, newline for newline. - Folded style (
>) joins consecutive lines with a single space instead of a newline, collapsing the block into one logical line — a blank line in the source becomes a line break in the output, but single line breaks between non-blank lines disappear.
literal_example: | Line one. Line two. Line three. folded_example: > Line one. Line two. Line three.
{
"literal_example": "Line one.\nLine two.\nLine three.\n",
"folded_example": "Line one. Line two. Line three.\n"
}A shell script or a multi-line SQL query embedded in a config file needs | — folding it would quietly turn SELECT *\nFROM users into SELECT * FROM userson a single line, which happens to still run, right up until a script relying on a specific line-oriented format (a heredoc, a certificate body, a changelog entry) breaks in a way that's hard to trace back to the block style. A long paragraph of prose in a description field is the right case for >, since the line breaks in the source are just there for the YAML file's own readability and were never meant to appear in the final string.
Why Convert to JSON at All?
Given that YAML and JSON represent the same underlying data, converting from one to the other can look like a purely cosmetic step. In practice, it's frequently a hard requirement rather than a preference. Plenty of APIs, request bodies, and tools are strict JSON-only consumers and will reject a YAML payload outright, even though the maps, lists, and scalars they need are identical to what the YAML document already encodes. A webhook endpoint expecting application/json, a JavaScript frontend calling JSON.parse(), a config value stored in a database column typed as JSON, or a third-party service's API that documents only a JSON schema — none of these accept a YAML document as-is, no matter how semantically equivalent it is.
That's the practical case for a dedicated yaml to json converter: not because JSON is a "better" format, but because the target consuming it doesn't speak YAML, and re-deriving the JSON by hand from a hand-authored YAML config is exactly the kind of manual, error-prone step a tool should absorb. The reverse direction matters just as often — turning a json to yaml response from an API into a readable, commentable config file to check into a repository, where the comment support and reduced punctuation actually help the humans maintaining it.
GenKitLab vs. Generic Online YAML-to-JSON Converters
| GenKitLab | Generic online converters | |
|---|---|---|
| Indentation error reporting | Exact line and column of the offending tab or misaligned indent | A generic parser exception, often with no line/column pointing at the real mistake |
| Bidirectional conversion | YAML → JSON and JSON → YAML in the same tool | Frequently one direction only, or two separate pages |
| Where processing happens | Entirely client-side, in your browser — nothing you paste is uploaded | Often server-side; a config file with secrets or internal hostnames leaves your machine |
| Anchors/aliases and block scalars | Fully resolved and expanded on conversion, with the merge-key extension supported | Inconsistent — some tools mishandle merge keys or multi-document files |
| Explains the gotchas (Norway problem, tabs vs. spaces) | This page | Rarely, if at all |
| Sign-up required | No | No, usually — but frequently ad-heavy |
The gap that matters most in practice is the first row. A parse failure on a real Kubernetes manifest or CI pipeline file is rarely obvious just from staring at it — the file often looks correctly indented in an editor with tab rendering set to a few columns wide. Getting told exactly which line and column the parser choked on turns a multi-minute manual scan into a five-second fix. GenKitLab's YAML formatter converts YAML to JSON and JSON to YAML, reformats a config file, and does exactly that — runs entirely client-side, with nothing you paste ever uploaded anywhere.
Explore More Config & DevOps Tools
YAML rarely lives in isolation — it usually sits next to other config formats in the same repository. A few tools that pair naturally with a yaml converter:
- ENV Parser — the same conversion problem one layer down: turn a flat
.envfile into structured JSON, or the other way around, for the config values that live outside a YAML manifest entirely. - Cron Expression Parser — decode the cron schedule string that shows up constantly inside a Kubernetes
CronJobmanifest or a CI pipeline's scheduled-trigger block, right next to the YAML it's embedded in. - JSON Formatter & Validator — once a YAML file converts to JSON, format and validate the result, or diff it against a previous version to see exactly what changed.
See the full DevOps tools category for the rest of the config-conversion and pipeline utilities in the same cluster.
Frequently asked questions
›How do I convert YAML to JSON online?
Paste the YAML document into GenKitLab's YAML formatter and it converts to JSON immediately, entirely in your browser — nothing you paste is uploaded to a server. The reverse direction, JSON to YAML, works the same way in the same tool, and any indentation problem is reported with the exact line and column rather than a generic parser error.
›Why does my YAML file fail to parse with a confusing error?
The overwhelmingly common cause is indentation — YAML's nesting is inferred purely from leading whitespace, the same way Python's is, and a single mixed tab, or a key indented one column off from its siblings, is enough to break parsing. Unlike JSON, where whitespace is purely cosmetic and can never change meaning, YAML whitespace is syntax. A good tool reports the exact line and column of the bad indentation instead of a generic scanner exception.
›What is the YAML Norway problem?
Under YAML 1.1 parsing rules, certain unquoted bare words — yes, no, on, off, and case variants like NO or Off — are implicitly read as booleans rather than strings. The name comes from the real-world case of writing the unquoted two-letter country code "NO" for Norway and getting back the boolean false instead of the string. The fix is to quote any string value that could be misread as a boolean or number.
›What are YAML anchors and aliases?
An anchor (&name) marks a node — a scalar, mapping, or sequence — as reusable elsewhere in the same document. An alias (*name) references that anchor, and the parser substitutes the anchored content in its place, avoiding having to repeat the same block verbatim. Converting a document using anchors to JSON fully expands every alias, since JSON has no equivalent reference mechanism.
›What's the difference between | and > in YAML multi-line strings?
| (literal style) preserves every line break in the block exactly as written. > (folded style) joins consecutive lines with a single space, collapsing them into one logical line, while a blank line still produces a line break. These aren't just formatting choices — they change the actual string content, so a multi-line shell script or SQL query needs | to keep its line breaks intact, while a wrapped paragraph of prose is usually a better fit for >.
›Why convert YAML to JSON instead of just using YAML directly?
Plenty of strict JSON-only consumers won't accept YAML even though the data model — nested maps, lists, and scalars — is identical: a webhook expecting application/json, a frontend calling JSON.parse(), or a third-party API documented only against a JSON schema. Converting is usually a practical necessity to satisfy that consumer, not a stylistic preference.
›Does converting YAML to JSON keep my comments?
No — comments are dropped, because JSON has no comment syntax at all to preserve them in. This is expected, not a bug in the converter. Keep the annotated YAML as the source of truth for anything a human edits, and treat the generated JSON as a downstream build artifact.
›Is there a YAML validator that shows the exact error location?
GenKitLab's YAML formatter validates on conversion and reports the precise line and column of a syntax problem — a mixed tab, a misaligned indent, an unclosed block scalar — instead of a generic, unhelpful parser stack trace. It runs entirely client-side, so a config file with internal hostnames or secrets never leaves your browser.
Last updated