Complete YAML 1.2 syntax reference with examples. Covers scalars, sequences, mappings, anchors, multi-line strings, and common pitfalls.
Plain unquoted string β most common
name: John Doe
Single-quoted: no variable or escape processing
path: '/usr/bin/node'
Double-quoted: supports escape sequences (\n, \t, etc.)
message: "Hello\nWorld"
Whole number (base 10)
port: 8080
Floating point number
threshold: 0.95
Boolean value β use only true/false (YAML 1.2)
debug: false
Null / absence of value
response: null
ISO 8601 date format
created: 2024-01-15T10:30:00Z
Single-line comment. No multi-line comment syntax.
# This is a comment key: value # inline comment
Force value to be treated as a specific type
port: !!str 8080 # string '8080' not int
Key-value pairs β indented block style
app: name: myapp port: 3000
Inline map β equivalent to block style
env: {NODE_ENV: prod, PORT: 8080}List of items β block style with dash+space
fruits: - apple - banana - cherry
Inline list β equivalent to block style
ports: [80, 443, 8080]
List where each item is a map
users:
- name: Alice
role: admin
- name: Bob
role: userArbitrarily deep nesting
database:
primary:
host: db1.example.com
port: 5432Merge the keys of a referenced mapping into current map
defaults: &defaults color: blue button: <<: *defaults text: Submit
Preserves newlines exactly as written
script: | #!/bin/bash echo "hello" exit 0
Newlines folded into spaces (great for long descriptions)
description: > This is a very long description that will be joined into one line.
Literal block, strip all trailing newlines
prompt: |- Enter value:
Literal block, keep all trailing newlines
template: |+ line1
Folded block, strip trailing newlines
message: >- This folds into one line no trailing newline
Assigns an anchor (label) to the current node
base: &base image: node:18 restart: always
References (copies) an anchored node
service1: <<: *base name: api service2: <<: *base name: worker
Anchor a scalar value to reuse it
read_timeout: &rto 30 write_timeout: *rto connect_timeout: *rto
Anchor a list
primary_colors: &colors - red - blue text_colors: *colors
Explicitly declare YAML version (optional, rarely needed)
%YAML 1.2 --- name: myapp
Marks the start of a YAML document. Required if using directives.
--- kind: Deployment --- kind: Service
Marks the end of a YAML document. Optional but useful.
--- debug: true ...
Multiple YAML docs in one file (stream)
Used in Kubernetes multi-resource files
Base64-encoded binary data
icon: !!binary | iVBORw0KGgo=
Indentation MUST use spaces only β never tabs
# WRONG: parent: \tchild: value # RIGHT: parent: child: value
Values containing ': ' (colon+space) must be quoted
# WRONG: url: http://example.com # RIGHT: url: "http://example.com"
1.0 parses as float! Quote or tag it to keep as string
version: '1.0' # string version: 1.0 # float
YAML 1.1 parses yes/no/on/off as booleans β quote to use strings
# YAML 1.1 (PyYAML): on: true # 'on' is boolean true! # Safe: always quote on: 'on'
Trailing spaces in keys are included in the key string
"key " (with space) != "key" β trim carefully
Duplicate keys β behavior is parser-specific (usually last wins). Treat as error.
Use a YAML linter to detect duplicate keys
| Feature | YAML | JSON |
|---|---|---|
| Comments | Yes: # comment | Not supported |
| Quotes required | Optional for strings | Required for strings |
| Anchors/aliases | Yes: &anchor / *alias | Not supported |
| Multi-line strings | Yes: | and > blocks | Escaped \n only |
| Tabs for indentation | Spaces only | Either |
| Is superset of JSON | All JSON is valid YAML | - |
| Human readability | Very high | Medium |
| Parser availability | High | Very high |
Critical: Many YAML parsers still use YAML 1.1 by default (Python's PyYAML, Ruby's Psych in some versions).
YAML is a superset of JSON β any valid JSON is valid YAML. YAML is designed to be more human-readable with less punctuation. It supports comments (# comment), anchors/aliases for deduplication, multi-line strings, and is whitespace-sensitive. JSON is better for machine-to-machine communication and data interchange; YAML is preferred for configuration files.
In YAML 1.1 (used by many parsers including PyYAML), 'on', 'off', 'yes', 'no' are valid boolean values. YAML 1.2 removed this behavior β only 'true' and 'false' are booleans. This is a common pitfall in CI/CD configs (e.g., 'on' in GitHub Actions is a workflow trigger keyword, not a YAML boolean). Always quote these values or use true/false explicitly.
Use the literal block scalar (|) to preserve newlines: each line in the block becomes a literal newline in the string. Use the folded block scalar (>) to fold newlines into spaces (great for long descriptions). Both support the - and + chomping indicators to control trailing newlines: |- strips trailing newlines, |+ keeps all trailing newlines.
YAML uses spaces for indentation β never tabs. All sibling keys must be at the same indentation level. A common cause is mixing tabs and spaces, or inconsistent indentation within sequences. Lists under a key must be indented by at least 1 space more than the parent key. Use a YAML linter or validator to quickly find indentation issues.