env.dev

YAML Syntax Cheat Sheet — Scalars, Collections & Gotchas

Quick reference for YAML syntax: strings, numbers, multiline values, sequences, mappings, anchors, aliases, and common gotchas like the Norway problem.

Last updated:

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.

SyntaxTypeValue
helloStringhello
"42"String42 (quoted forces string)
42Integer42
3.14Float3.14
0xFFInteger255 (hexadecimal)
0o77Integer63 (octal)
1.0e+3Float1000.0 (scientific notation)
.infFloatPositive infinity
-.infFloatNegative infinity
.nanFloatNot a number
trueBooleantrue
falseBooleanfalse
nullNullnull
~Nullnull (tilde shorthand)
Nullnull (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.

StyleDescription
plainNo 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
String examples
# 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.

IndicatorNameBehavior
|Literal blockPreserves newlines exactly as written
>Folded blockFolds newlines into spaces; blank lines become newlines
|-Literal stripSame as | but strips trailing newline
>-Folded stripSame as > but strips trailing newline
|+Literal keepSame as | but keeps all trailing newlines
>+Folded keepSame as > but keeps all trailing newlines
Literal vs folded
# 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 here

Sequences (Lists)

Sequences are ordered lists of values. Use a dash followed by a space (- ) for block style, or square brackets for flow style.

Block-style sequence
fruits:
  - apple
  - banana
  - cherry
Flow-style sequence
fruits: [apple, banana, cherry]

Mappings (Dictionaries)

Mappings are unordered key-value pairs. Use key: value for block style or curly braces for flow style.

Block-style mapping
server:
  host: localhost
  port: 8080
  debug: true
Flow-style mapping
server: {host: localhost, port: 8080, debug: true}

Nested Structures

YAML uses indentation to represent nesting. You can freely combine mappings and sequences at any depth.

Nested mappings and sequences
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: secret
List of objects
users:
  - name: Alice
    role: admin
    permissions:
      - read
      - write
      - delete
  - name: Bob
    role: viewer
    permissions:
      - read

Block 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.

FeatureBlock StyleFlow Style
Sequences- item[item1, item2]
Mappingskey: value{key: value}
ReadabilityBetter for large/nested dataBetter for short inline data
NestingIndentation-basedBrace/bracket-based
Mixing block and flow
# 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.

Comments
# Full-line comment
name: app  # Inline comment

# Comments cannot appear inside scalars
# This is NOT a comment: "hello # world" -> the # is part of the string

Anchors, Aliases, and Merge Keys

Anchors (&) define reusable nodes, aliases (*) reference them, and the merge key (<<) merges mappings. This eliminates duplication in repetitive configs.

Anchors and aliases
# 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_prod
Scalar anchor
default_timeout: &timeout 30

services:
  api:
    timeout: *timeout
  worker:
    timeout: *timeout

Multi-Document Files

A single YAML file can contain multiple documents separated by ---. An optional ... marks the end of a document.

Multiple documents
---
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

FeatureYAMLJSON
CommentsYes (#)No
Quoting keysOptionalRequired (double quotes)
Quoting stringsOptionalRequired (double quotes)
Multiline stringsNative (| and >)No (use \n)
Trailing commasN/A (no commas)Not allowed
Anchors/aliasesYesNo
Multiple documentsYes (---)No
Data typesStrings, numbers, booleans, null, datesStrings, numbers, booleans, null
IndentationSignificant (spaces only)Not significant
SupersetJSON is valid YAML (1.2+)N/A
File extensions.yaml, .yml.json
Parsing speedSlowerFaster

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 ValueYAML 1.1 InterpretationFix
NOfalse"NO"
YEStrue"YES"
nofalse"no"
yestrue"yes"
ontrue"on"
offfalse"off"
ytrue"y"
nfalse"n"
Norway problem
# 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.

Type coercion surprises
# 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.

Colon pitfall
# 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.

Was this helpful?

Frequently Asked Questions

What is the Norway problem in YAML?

In YAML 1.1, the country code NO is interpreted as boolean false because YAML treats bare yes/no/on/off as booleans. Always quote country codes and similar values. YAML 1.2 fixes this by only treating true/false as booleans.

Can I use tabs for indentation in YAML?

No. YAML only allows spaces for indentation. Tabs will cause a parse error. Most editors can be configured to insert spaces when you press Tab.