ENES
yamlEngineering Guide

YAML Config Errors: Why Tabs, Indentation, and 'no' Break Your File (2026)

AC
Alex Chen·Lead Systems Architect
Published on 2026-09-06·9 min read·Daily Toolbox Engineering

YAML Config Errors: Why Tabs, Indentation, and 'no' Break Your File (2026)

Your CI pipeline fails with "did not find expected key." Your Kubernetes deployment silently uses the wrong value. Your country code NO (Norway) becomes false. Your version 1.20 becomes 1.2.

YAML looks simple but is full of traps. Its "human-friendly" design hides surprising type coercion and whitespace rules that cause silent, hard-to-debug config errors.

This guide covers the exact YAML gotchas that break config files—tabs, indentation, type coercion, and multi-line strings—with the rules to avoid them.


Trap 1: Tabs Are Forbidden

The rule

YAML does not allow tabs for indentation. Ever. Only spaces.

server:
	port: 8080     # ← TAB here = parse error

Error: found character that cannot start any token

Why it's insidious

Your editor may show tabs and spaces identically. You copy-paste from somewhere that used tabs. The file looks perfectly aligned but fails to parse.

The fix

  • Configure your editor: "insert spaces instead of tabs"
  • Set YAML files to 2-space indentation
  • Enable "show whitespace" to catch stray tabs
  • Use a YAML linter (yamllint) in CI

Trap 2: Indentation Defines Structure

Indentation = nesting

Unlike JSON's braces, YAML uses indentation depth to define structure. Wrong indentation = wrong data (or a parse error).

# These mean completely different things:

# Version A: port is inside server
server:
  port: 8080

# Version B: port is a sibling of server (top-level!)
server:
port: 8080

The silent bug

Sometimes wrong indentation doesn't error—it just produces the wrong structure:

database:
  host: localhost
  port: 5432
   timeout: 30    # ← 3 spaces instead of 2

Depending on the parser, timeout may be misplaced or error. Consistency is everything.

Rules

  • Pick one indent width (2 spaces is convention) and never mix
  • List items align under their key:
fruits:
  - apple
  - banana
  • Never use tabs (see Trap 1)

Trap 3: The Norway Problem (boolean coercion)

The classic bug

countries:
  - GB
  - NO
  - FR

What YAML 1.1 parsers see:

["GB", false, "FR"]

NO (Norway) became the boolean false!

The full list of surprise booleans (YAML 1.1)

These unquoted values become booleans:

Becomes true Becomes false
yes, Yes, YES no, No, NO
true, True false, False
on, On, ON off, Off, OFF
y, Y n, N

The fix: quote strings that look like booleans

countries:
  - "GB"
  - "NO"    # ← quoted, stays a string
  - "FR"

Note: YAML 1.2 (used by newer parsers) removed yes/no/on/off, but many tools still use 1.1 semantics. When in doubt, quote it.


Trap 4: Number Coercion

Leading zeros and version strings

version: 1.20        # → 1.2 (trailing zero lost — it's a float!)
zip: 01234           # → 668 (octal!) or 1234, depending on parser
build: 010           # → 8 (octal interpretation)
phone: 5551234       # → 5551234 (number, loses any formatting)

The fixes

version: "1.20"      # quote to keep exact string
zip: "01234"         # quote codes/IDs
build: "010"         # quote to avoid octal
phone: "5551234"     # quote — it's an identifier, not math

Rule: If a value is an identifier, code, or version (not something you'll do math on), quote it.


Trap 5: Special Characters Need Quoting

Characters that break unquoted values

time: 10:30          # ← colon: parsed as {10: 30} map, not a time!
price: $9.99         # usually fine, but risky
ratio: 3:2           # ← colon problem again
path: C:\Users       # ← colon + backslash
greeting: hello: world  # ← colon mid-value = error

The fix

time: "10:30"
ratio: "3:2"
path: "C:\\Users"    # also escape backslash in double quotes
greeting: "hello: world"

Single vs double quotes

Quote Escapes? Use for
'single' No escaping (literal) Strings with backslashes, no escapes needed
"double" Yes (\n, \t, \) Strings needing escape sequences
literal: 'C:\Users\file'      # backslashes stay literal
escaped: "line1\nline2"        # \n becomes a newline

Trap 6: Multi-line Strings (| vs >)

The two block styles

# Literal block (|) — keeps newlines
description: |
  Line one
  Line two
# Result: "Line one\nLine two\n"

# Folded block (>) — folds newlines into spaces
summary: >
  This is one
  long line
# Result: "This is one long line\n"

Chomping indicators (controlling the trailing newline)

keep: |+     # keep all trailing newlines
clip: |      # single trailing newline (default)
strip: |-    # no trailing newline

Common bug

Using > (fold) when you need | (literal), turning a multi-line script or key into one mangled line. For shell scripts, SSH keys, or certificates in YAML, always use |.


Trap 7: Anchors and References (the hidden feature)

YAML can reference repeated content—useful but surprising if you don't know it:

defaults: &defaults      # define anchor
  timeout: 30
  retries: 3

production:
  <<: *defaults          # merge the anchor
  host: prod.example.com

staging:
  <<: *defaults
  host: staging.example.com

Both production and staging inherit timeout and retries. If you see &name and *name, that's what's happening.


Validation Checklist

Before deploying a YAML config:

☐ No tabs (spaces only)
☐ Consistent indentation (2 spaces, never mixed)
☐ Quote boolean-like strings ("NO", "yes", "off")
☐ Quote codes/versions ("01234", "1.20")
☐ Quote values with colons ("10:30")
☐ Right block style (| for literal, > for folded)
☐ Lint it (yamllint config.yaml)
☐ Validate against schema if available


Quick Debugging

"did not find expected key" → indentation error or tab
Value is false but should be text → the Norway/boolean problem, quote it
Version lost a digit → number coercion, quote it
"mapping values are not allowed here" → unquoted colon in a value
Multi-line value is one line → used > instead of |


FAQ

Q: Why does my YAML fail with "found character that cannot start any token"?
A: You have a tab character. YAML forbids tabs for indentation—replace all tabs with spaces.

Q: Why did NO become false?
A: The "Norway problem." YAML 1.1 treats no, yes, on, off as booleans. Quote the value: "NO".

Q: How do I keep 1.20 from becoming 1.2?
A: Unquoted, it's parsed as a float. Quote it: "1.20".

Q: When do I use | vs >?
A: | (literal) preserves newlines—use for scripts, keys, certificates. > (folded) joins lines with spaces—use for long prose.

Q: Should I just use JSON instead?
A: JSON has no comments and is stricter (which avoids these traps), but YAML is more readable for config. If YAML's traps bite you often, JSON or TOML are safer alternatives.


Conclusion

YAML's readability hides sharp edges. Avoid config disasters by remembering:

  1. Spaces only, never tabs
  2. Consistent indentation defines structure
  3. Quote boolean-like strings (the Norway problem)
  4. Quote codes and versions (number coercion)
  5. Quote values with colons
  6. Right multi-line style (| vs >)
  7. Lint before deploy

When in doubt, quote it. A quoted string is almost never wrong; an unquoted value can silently become the wrong type.

#yaml#config#devops#parsing#type-coercion
AC
Written by Alex ChenLead Architect

Alex Chen is a distributed systems engineer and core maintainer at Daily Toolbox with over 10 years of experience in client-side web technologies, RFC standards compliance, and cryptographic protocols. He specializes in zero-knowledge client architectures and WebAssembly-accelerated algorithms.

Try the free tools mentioned above

⚡ Open YAML to JSON Converter →