A tour of YAML 1.2 syntax
YAML is a human-friendly data serialization language used for configuration in tools like Docker Compose, Kubernetes, GitHub Actions and CI pipelines. This reference covers the building blocks — scalars, sequences, mappings, anchors, tags and multi-document streams — alongside the quoting traps that catch almost everyone at least once.
Core structure: indentation, mappings, sequences
Structure comes from indentation (spaces only, never tabs). A colon-space makes a mapping entry; a dash-space makes a sequence element:
service:
name: web
ports: [80, 443]
env:
- DEBUG=1
base: &defaults
retries: 3
worker:
<<: *defaults
name: worker
A single tab character anywhere in the file is a parse error — not a warning, an error. Most editors can be configured to convert tab to spaces automatically; in YAML files that setting is worth turning on.
Scalar styles
YAML offers three quoting modes for scalars, each with different escape rules:
| Style | Syntax | Escape sequences | Best for |
|---|---|---|---|
| Plain (unquoted) | value | none | Simple strings, numbers, true booleans |
| Single-quoted | 'value' | only '' for a literal quote | Strings that should not be interpreted at all |
| Double-quoted | "value" | \n, \t, \uXXXX, etc. | Strings needing real escape sequences |
The literal block (|) preserves every newline exactly — useful for shell scripts or SQL embedded in config. The folded block (>) converts single newlines to spaces and blank lines to newlines — useful for long prose paragraphs.
Anchors, aliases, and the merge key
Anchors (&name) mark a node for reuse; aliases (*name) reference it elsewhere. The merge key (<<:) lets you pull a mapping’s keys into another mapping — the YAML equivalent of object spread:
defaults: &defaults
timeout: 30
retries: 3
production:
<<: *defaults
timeout: 60 # overrides the anchor value
Without anchors you would duplicate retries: 3 in every environment block, creating drift when the value needs to change.
The classic gotchas
The Norway problem: in YAML 1.1, the unquoted scalar NO parses as the boolean false (because it was a recognized boolean synonym). This caught users who wrote country: NO for Norway. YAML 1.2 fixes this — only true and false are booleans — but many parsers still default to 1.1 behaviour. Quote country codes, toggle strings, and other ambiguous values to be safe.
Base-60 integer parsing: in YAML 1.1, 22:30 is parsed as 22×60 + 30 = 1350. This bites time-of-day values, port pairs, and minute:second durations. Always quote time-like scalars.
Octal integers: leading zeros trigger octal parsing in YAML 1.1. 0755 becomes 493 in decimal. Quote file permission strings.
Trailing spaces after colons: key :value (space before colon) is not a mapping entry — the key is key with a trailing space. The colon-space pair key: value is canonical.
Tips for CI and Kubernetes configs
- Use spaces for indentation; a single tab anywhere is a parse error.
- Prefer the 1.2 core schema where only
true/falseare booleans. - Quote times like
22:22, ports, and leading-zero IDs to dodge base-60/octal parsing. - Separate multiple documents in one file with
---, and end optionally with.... - Validate YAML files in CI before deploying — a one-character indentation error in a Kubernetes manifest silently breaks the entire deployment.