DEV Community

楊東霖
楊東霖

Posted on • Originally published at devplaybook.cc

YAML Validator Online: Lint and Format YAML Files

YAML is everywhere in modern development. Your CI/CD pipelines, Kubernetes manifests, Docker Compose files, Ansible playbooks, GitHub Actions workflows, and application configuration files are almost certainly written in YAML. And yet, YAML is also notorious for being deceptively fragile. A single misplaced space, an errant tab, or an ambiguous string literal can break your entire deployment — often with a cryptic error message.

This guide covers YAML validation and linting in depth: what makes YAML tricky, what a validator actually checks, common errors and how to fix them, and when to reach for an online YAML validator instead of running tooling locally.

What Is YAML and Why Is It Error-Prone?

YAML (YAML Ain't Markup Language) is a human-readable data serialization format. Its design goal was to be more readable than JSON or XML, using indentation to represent structure instead of brackets and tags.

That readability comes at a cost: YAML is whitespace-sensitive in ways that are easy to get wrong. The parser uses indentation to determine the structure of your document, and it has opinions about things like implicit type coercion that can produce surprising results.

Here's a taste of the weirdness:

# These look similar but mean very different things
key1: yes      # parsed as boolean true
key1: "yes"    # parsed as the string "yes"

key2: 1.0      # parsed as float
key2: "1.0"    # parsed as string

key3:          # null value
key3: ~        # also null
key3: null     # also null
Enter fullscreen mode Exit fullscreen mode

The implicit type coercion in YAML 1.1 (used by many parsers) is a particularly famous source of bugs — the so-called "Norway problem" where the country code NO is parsed as boolean false. YAML 1.2 fixed many of these issues, but library support is inconsistent.

What Does a YAML Validator Check?

A YAML validator performs several layers of checking:

Syntax Validation

The most basic check: is this valid YAML that a parser can process without errors?

  • Proper indentation (consistent spaces, no tabs mixed in)
  • Correct use of colons, dashes, and brackets
  • Properly quoted strings
  • Valid escape sequences
  • Balanced brackets and braces (for flow style)

Structure Validation

Does the document represent a valid data structure?

  • Keys in mappings are unique (duplicate keys are technically invalid, though some parsers accept them)
  • Sequences use consistent dash notation
  • Anchors and aliases are properly defined and referenced

Semantic Linting

More advanced linters check for style and best practices:

  • Trailing whitespace
  • Inconsistent indentation width
  • Lines that exceed a maximum length
  • Truthy values that should be quoted (yes, no, on, off, true, false)
  • Octal numbers that might be misinterpreted

YAML Indentation Rules

Indentation is where most YAML errors originate. The rules:

  1. Use spaces, not tabs. Tabs are explicitly forbidden in YAML. This is non-negotiable.
  2. Be consistent within a block. All items at the same level must use the same indentation.
  3. Child elements must be indented more than their parent. There's no rule about how many spaces, but 2 is conventional.
# CORRECT
parent:
  child1: value1
  child2: value2
  nested:
    grandchild: value3

# WRONG — inconsistent indentation
parent:
  child1: value1
    child2: value2   # ← indented too much, now looks like child of child1
Enter fullscreen mode Exit fullscreen mode

Indentation and Sequences

List items use a dash (-) followed by a space. The dash itself counts as part of the indentation:

# Items at the top level
- item1
- item2

# Items nested under a key
fruits:
  - apple
  - banana
  - cherry

# Sequence of mappings
people:
  - name: Alice
    age: 30
  - name: Bob
    age: 25
Enter fullscreen mode Exit fullscreen mode

A common mistake is inconsistent placement of the dash relative to the mapping keys:

# WRONG — the keys after the dash are at different levels
people:
  - name: Alice
   age: 30      # ← this is at wrong indentation level

# CORRECT — both keys at same level relative to the dash
people:
  - name: Alice
    age: 30
Enter fullscreen mode Exit fullscreen mode

Common YAML Errors and How to Fix Them

Tabs Instead of Spaces

Symptom:

yaml.scanner.ScannerError: while scanning for the next token found character '\t' that cannot start any token
Enter fullscreen mode Exit fullscreen mode

Fix: Replace all tabs with spaces. In most editors, you can set "convert tabs to spaces" or use a command like:

expand -t 2 config.yaml > config_fixed.yaml
Enter fullscreen mode Exit fullscreen mode

Duplicate Keys

Symptom: No error, but one of your keys silently disappears.

# WRONG — duplicate key
database:
  host: localhost
  port: 5432
  host: production.db.example.com  # ← overwrites the first 'host'
Enter fullscreen mode Exit fullscreen mode

Most parsers accept duplicate keys but use the last value, silently discarding the earlier one. A linter will flag this as an error.

Unquoted Special Characters

Symptom:

yaml.scanner.ScannerError: mapping values are not allowed here
Enter fullscreen mode Exit fullscreen mode

Colons, brackets, and other special characters can confuse the parser when unquoted:

# WRONG
message: Error: something went wrong
url: http://example.com/path?key=value&other=data

# CORRECT
message: "Error: something went wrong"
url: "http://example.com/path?key=value&other=data"
Enter fullscreen mode Exit fullscreen mode

Implicit Type Coercion Surprises

# WRONG if you want strings
enabled: yes       # becomes boolean true
port: 08080        # the leading zero makes this an octal literal in YAML 1.1!
version: 1.0       # becomes float, may serialize back as "1" without decimal

# CORRECT
enabled: "yes"
port: "08080"
version: "1.0"
Enter fullscreen mode Exit fullscreen mode

The port example is particularly dangerous in old-style YAML parsers — 0777 is the octal value 511, not 777.

Multiline String Confusion

YAML has two multiline string notations that behave differently:

# Literal block scalar — preserves newlines
description: |
  Line one
  Line two
  Line three

# Folded block scalar — newlines become spaces (except blank lines)
description: >
  This is a long sentence
  that continues here
  and ends here.

  New paragraph starts after blank line.
Enter fullscreen mode Exit fullscreen mode

Forgetting which one you're using leads to unexpected whitespace in your strings.

Anchor and Alias Errors

# Define an anchor
defaults: &defaults
  timeout: 30
  retries: 3

# Reference it with an alias
production:
  <<: *defaults    # merge key — copies all keys from defaults
  host: prod.example.com

# WRONG — referencing undefined anchor
staging:
  <<: *undefined_anchor  # ParseError
Enter fullscreen mode Exit fullscreen mode

YAML in CI/CD Pipelines

YAML errors in CI/CD are particularly painful because they often only surface at runtime, causing pipeline failures with confusing error messages. Here are the most common pitfalls:

GitHub Actions

# Common mistake — string that looks like a number
on:
  push:
    branches:
      - main

# WRONG — 'on' is a YAML truthy value! Quote it or use the longer form
"on":
  push:
    branches:
      - main
Enter fullscreen mode Exit fullscreen mode

Kubernetes Manifests

# Integer vs string port — matters for some tools
ports:
  - containerPort: 8080    # integer
  - containerPort: "8080"  # string — some validators warn about this

# Resource limits — must be strings
resources:
  limits:
    memory: "256Mi"   # CORRECT
    memory: 256Mi     # WRONG — Mi suffix makes this a string anyway, but be explicit
Enter fullscreen mode Exit fullscreen mode

Docker Compose

# Version field — should be a string
version: "3.8"   # CORRECT
version: 3.8     # Parsed as float 3.8, may cause issues

# Environment variables — be careful with special characters
environment:
  DATABASE_URL: "postgres://user:pass@host:5432/db"  # Quote the URL
  API_KEY: "${SECRET_KEY}"   # Variable substitution
Enter fullscreen mode Exit fullscreen mode

YAML Linting Tools

yamllint

The standard Python YAML linter. Install with pip install yamllint and configure with .yamllint:

# .yamllint configuration
extends: default
rules:
  line-length:
    max: 120
  truthy:
    allowed-values: ['true', 'false']
  indentation:
    spaces: 2
    indent-sequences: true
Enter fullscreen mode Exit fullscreen mode

Run it:

yamllint config.yaml
yamllint -d relaxed docker-compose.yml
Enter fullscreen mode Exit fullscreen mode

VS Code Extensions

  • YAML by Red Hat — syntax highlighting, schema validation, formatting
  • YAML Lint — inline linting as you type

Language-Specific Libraries

# Python — use PyYAML or ruamel.yaml
import yaml

try:
    with open('config.yaml') as f:
        data = yaml.safe_load(f)
except yaml.YAMLError as e:
    print(f"YAML Error: {e}")
Enter fullscreen mode Exit fullscreen mode
// Node.js — use js-yaml
const yaml = require('js-yaml');

try {
  const doc = yaml.load(fs.readFileSync('config.yaml', 'utf8'));
} catch (e) {
  console.error('YAML Error:', e.message);
}
Enter fullscreen mode Exit fullscreen mode

When to Use an Online YAML Validator

Running yamllint locally requires Python, pip, and a config file. That's fine for a project, but overkill when you just need to quickly check a YAML snippet. An online validator is the right tool when:

  • You're debugging a CI/CD pipeline failure and want to validate the YAML before pushing again
  • You copied YAML from documentation or Stack Overflow and want to verify it's valid before using it
  • You're writing a Kubernetes manifest or Helm chart and want instant feedback on structure
  • You're on a new machine or container where tooling isn't installed
  • You need to quickly format and pretty-print a YAML file that's been minimized or hand-edited
  • You want to convert between JSON and YAML — most online validators support this in both directions

FAQ

Q: Is YAML a superset of JSON?

YAML 1.2 is a superset of JSON — every valid JSON document is also valid YAML 1.2. In practice, the libraries you use matter. PyYAML implements YAML 1.1, which doesn't fully support JSON's escape sequences. js-yaml defaults to YAML 1.2 compatibility.

Q: Why does my YAML work locally but fail in production?

Different YAML libraries implement different versions of the spec with different default behaviors. The most common culprit is YAML 1.1 vs 1.2 type coercion differences. Another common cause: your local tool is more lenient about duplicate keys or tabs than the production parser.

Q: How do I validate YAML against a JSON Schema?

Tools like yamllint focus on syntax. For schema validation (validating that your YAML has the right structure and types), you need a JSON Schema validator that accepts YAML input. The Red Hat YAML VS Code extension supports this with # yaml-language-server: $schema=... comments at the top of your file.

Q: What's the difference between block style and flow style YAML?

Block style uses indentation:

person:
  name: Alice
  hobbies:
    - reading
    - coding
Enter fullscreen mode Exit fullscreen mode

Flow style uses JSON-like brackets:

person: {name: Alice, hobbies: [reading, coding]}
Enter fullscreen mode Exit fullscreen mode

Both are valid. Flow style is more compact but less readable for nested structures.

Q: How do I represent an empty value in YAML?

key:           # implicit null
key: ~         # explicit null
key: null      # also null
key: ""        # empty string — NOT null
key: []        # empty sequence
key: {}        # empty mapping
Enter fullscreen mode Exit fullscreen mode

Validate Your YAML Instantly

Tired of pushing to CI only to discover your YAML had a tab on line 47? The DevPlaybook YAML Validator gives you instant validation and formatting in your browser — no install, no setup, no pushing broken configs.

Paste your YAML, see the errors highlighted with line numbers and clear explanations, fix them, and you're done.

Open YAML Validator →

It handles syntax validation, structure checking, and pretty-printing for everything from simple config files to multi-document Kubernetes manifests. Catch the error before it catches you.


Level Up Your Dev Workflow

Found this useful? Explore DevPlaybook — cheat sheets, tool comparisons, and hands-on guides for modern developers.

🛒 Get the DevToolkit Starter Kit on Gumroad — 40+ browser-based dev tools, source code + deployment guide included.

Top comments (0)