YAML (YAML Ain't Markup Language) is a human-readable data serialization format widely used for configuration files, CI/CD pipelines (most notably GitHub Actions workflows), Kubernetes manifests, and infrastructure-as-code. This cheat sheet covers every core syntax rule, from scalars and collections to anchors, multi-document files, and common pitfalls. Convert between formats instantly with the YAML-JSON Converter.
Basic Scalar Types
YAML supports strings, integers, floats, booleans, and null as scalar values. Types are inferred automatically unless explicitly quoted.
| Syntax | Type | Value |
|---|---|---|
| hello | String | hello |
| "42" | String | 42 (quoted forces string) |
| 42 | Integer | 42 |
| 3.14 | Float | 3.14 |
| 0xFF | Integer | 255 (hexadecimal) |
| 0o77 | Integer | 63 (octal) |
| 1.0e+3 | Float | 1000.0 (scientific notation) |
| .inf | Float | Positive infinity |
| -.inf | Float | Negative infinity |
| .nan | Float | Not a number |
| true | Boolean | true |
| false | Boolean | false |
| null | Null | null |
| ~ | Null | null (tilde shorthand) |
| Null | null (empty value) |
How Do Strings Work in YAML?
YAML offers four ways to write strings: plain (unquoted), single-quoted, double-quoted, and multiline block scalars. Each behaves differently with escaping and whitespace.
| Style | Description |
|---|---|
| plain | No quotes needed for simple strings; no escape sequences |
| 'single-quoted' | Literal text; only escape is '' for a literal single quote |
| "double-quoted" | Supports escape sequences: \n, \t, \\, \", \uNNNN |
# Plain string
name: hello world
# Single-quoted — no escape processing
path: 'C:\Users\docs'
apostrophe: 'it''s here'
# Double-quoted — escape sequences work
greeting: "hello\nworld"
unicode: "\u00e9 = e with acute"Multiline Strings: Block Scalars
The pipe (|) preserves line breaks (literal block), while the angle bracket (>) folds lines into a single line (folded block). Append - to strip the trailing newline or + to keep all trailing newlines.
| Indicator | Name | Behavior |
|---|---|---|
| | | Literal block | Preserves newlines exactly as written |
| > | Folded block | Folds newlines into spaces; blank lines become newlines |
| |- | Literal strip | Same as | but strips trailing newline |
| >- | Folded strip | Same as > but strips trailing newline |
| |+ | Literal keep | Same as | but keeps all trailing newlines |
| >+ | Folded keep | Same as > but keeps all trailing newlines |
# Literal block — newlines preserved
description: |
Line one
Line two
Line three
# Result: "Line one\nLine two\nLine three\n"
# Folded block — newlines become spaces
summary: >
This is a long
sentence that gets
folded into one line.
# Result: "This is a long sentence that gets folded into one line.\n"
# Strip trailing newline
clean: |-
no trailing newline hereSequences (Lists)
Sequences are ordered lists of values. Use a dash followed by a space (- ) for block style, or square brackets for flow style.
fruits:
- apple
- banana
- cherryfruits: [apple, banana, cherry]Mappings (Dictionaries)
Mappings are unordered key-value pairs. Use key: value for block style or curly braces for flow style.
server:
host: localhost
port: 8080
debug: trueserver: {host: localhost, port: 8080, debug: true}Nested Structures
YAML uses indentation to represent nesting. You can freely combine mappings and sequences at any depth.
database:
primary:
host: db-primary.example.com
port: 5432
replicas:
- host: db-replica-1.example.com
port: 5432
- host: db-replica-2.example.com
port: 5432
credentials:
username: admin
password: secretusers:
- name: Alice
role: admin
permissions:
- read
- write
- delete
- name: Bob
role: viewer
permissions:
- readBlock Style vs Flow Style
Block style uses indentation for structure. Flow style uses inline indicators ({}, []) like JSON. You can mix both in a single document.
| Feature | Block Style | Flow Style |
|---|---|---|
| Sequences | - item | [item1, item2] |
| Mappings | key: value | {key: value} |
| Readability | Better for large/nested data | Better for short inline data |
| Nesting | Indentation-based | Brace/bracket-based |
# Block style with flow-style values
endpoints:
- path: /api/users
methods: [GET, POST]
headers: {Content-Type: application/json}
- path: /api/health
methods: [GET]Comments
Comments start with # and run to the end of the line. There are no block comments in YAML. Comments can appear on their own line or inline after a value.
# Full-line comment
name: app # Inline comment
# Comments cannot appear inside scalars
# This is NOT a comment: "hello # world" -> the # is part of the stringAnchors, Aliases, and Merge Keys
Anchors (&) define reusable nodes, aliases (*) reference them, and the merge key (<<) merges mappings. This eliminates duplication in repetitive configs.
# Define an anchor
defaults: &defaults
adapter: postgres
host: localhost
port: 5432
# Reference with alias
development:
database:
<<: *defaults
database: myapp_dev
production:
database:
<<: *defaults
host: db.prod.example.com
database: myapp_proddefault_timeout: &timeout 30
services:
api:
timeout: *timeout
worker:
timeout: *timeoutMulti-Document Files
A single YAML file can contain multiple documents separated by ---. An optional ... marks the end of a document.
---
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
env: production
---
apiVersion: v1
kind: Secret
metadata:
name: app-secret
type: Opaque
data:
password: cGFzc3dvcmQ=
...YAML vs JSON Comparison
| Feature | YAML | JSON |
|---|---|---|
| Comments | Yes (#) | No |
| Quoting keys | Optional | Required (double quotes) |
| Quoting strings | Optional | Required (double quotes) |
| Multiline strings | Native (| and >) | No (use \n) |
| Trailing commas | N/A (no commas) | Not allowed |
| Anchors/aliases | Yes | No |
| Multiple documents | Yes (---) | No |
| Data types | Strings, numbers, booleans, null, dates | Strings, numbers, booleans, null |
| Indentation | Significant (spaces only) | Not significant |
| Superset | JSON is valid YAML (1.2+) | N/A |
| File extensions | .yaml, .yml | .json |
| Parsing speed | Slower | Faster |
Common Gotchas and Pitfalls
The Norway Problem: Unquoted Values Interpreted as Booleans
In YAML 1.1, many strings are silently interpreted as booleans. The most infamous example: the country code NO (Norway) becomes false. YAML 1.2 restricts booleans to only true and false, but many parsers still use YAML 1.1 rules.
| Unquoted Value | YAML 1.1 Interpretation | Fix |
|---|---|---|
| NO | false | "NO" |
| YES | true | "YES" |
| no | false | "no" |
| yes | true | "yes" |
| on | true | "on" |
| off | false | "off" |
| y | true | "y" |
| n | false | "n" |
# Dangerous — NO becomes false in YAML 1.1 parsers
countries:
- DK
- NO # parsed as boolean false!
- SE
# Safe — always quote ambiguous values
countries:
- "DK"
- "NO"
- "SE"Indentation: Spaces Only, Never Tabs
YAML forbids tabs for indentation. Use spaces only (2 spaces is the most common convention). Inconsistent indentation causes parse errors. Most editors can be configured to insert spaces when Tab is pressed.
Strings That Look Like Other Types
Values that resemble numbers, booleans, or timestamps are auto-cast. Always quote values when the string representation matters.
# These are NOT strings without quotes
version: 1.0 # float 1.0, not string "1.0"
version: 1.10 # float 1.1 (trailing zero lost!)
zip: 01onal # string (not a valid number, so stays string)
zip: 01onal # but...
zipcode: 07110 # octal 3656 in YAML 1.1, string in YAML 1.2!
date: 2024-01-01 # datetime object, not string
# Safe — quote when you mean strings
version: "1.0"
version: "1.10"
zipcode: "07110"
date: "2024-01-01"Colon in Values
A colon followed by a space (: ) starts a mapping value. If your string contains this pattern, you must quote it.
# Error — YAML sees "http" as a key
url: http://example.com # actually works (no space after ://)
# Error — space after colon triggers mapping
message: Note: this breaks
# Fix
message: "Note: this breaks"Frequently Asked Questions
What is the difference between .yaml and .yml?
There is no difference. Both extensions are recognized. The YAML specification recommends .yaml, but .yml is common in older tools and ecosystems like Ruby on Rails.
Is JSON valid YAML?
Yes, as of YAML 1.2. Every valid JSON document is also a valid YAML document. YAML 1.2 was explicitly designed to be a superset of JSON.
How do you represent an empty value in YAML?
Leave the value blank (key:), use null, or use the tilde (~). All three produce a null value.
Can YAML keys be non-strings?
The spec allows any valid YAML node as a key, including numbers, booleans, and even sequences. However, most language bindings only support string keys, and using non-string keys is generally discouraged.
How do you escape special characters in YAML?
Use double-quoted strings for escape sequences: \n (newline), \t (tab), \\ (backslash), \" (double quote), and \uNNNN (Unicode). Single-quoted strings do not process escapes except '' for a literal single quote.
How many spaces should I use for indentation?
YAML requires at least 1 space, but 2 spaces is the most common convention. The key rule is consistency within a file. Never use tabs.