ToolSite
All posts

YAML Indentation Errors and How to Fix Them

YAML indentation errors are the top cause of broken Kubernetes manifests. Learn to spot, debug, and fix them with our free YAML validator and converter tools.

By ToolSite4 min readguides

Why YAML Indentation Breaks Things

YAML uses indentation to define structure. Unlike JSON, which uses braces and brackets, YAML infers parent-child relationships from the number of spaces before each line. A two-space indentation means one level of nesting. A four-space indentation means two levels.

If a line has three spaces when it should have four, YAML silently changes the structure. The file is syntactically valid but semantically wrong. This is the source of most YAML-related production incidents. Kubernetes applies the manifest you give it, not the manifest you meant to write.

How YAML Parses Indentation

Take a simple Kubernetes Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.25

metadata is indented zero spaces, it's a top-level key. name is indented two spaces, it's a child of metadata. labels is indented four spaces from template, making it a child of metadata which is a child of template.

If labels were indented two spaces instead of four, it would become a child of spec directly. Kubernetes would reject the manifest or, worse, apply a misconfigured deployment that runs but does the wrong thing.

Understanding the nesting path is essential. In the example above, the full path to labels is spec.template.metadata.labels. Each dot represents one level of indentation. If any level is off by even one space, the path breaks and the key ends up in the wrong parent.

The Most Common Indentation Bug

You have a multi-line block and need to paste a snippet from another file:

env:
  - name: DATABASE_URL
    value: postgresql://...
    # This block was pasted with wrong indentation
    - name: REDIS_URL
    value: redis://...

The second - name: REDIS_URL is indented four spaces. It's now a child of value, not a sibling of the first - name. The parser sees it as a list inside a string value. This is hard to spot visually because the lines look aligned in the editor, but they're aligned at the wrong column.

Fix: use an editor with YAML indent guides. VS Code shows vertical lines at each indentation level, making it obvious when a line is at the wrong column. Always paste with proper indentation, or paste and then re-indent the block using your editor's indent adjustment commands. A YAML validator will catch this before you apply the configuration.

Tabs vs Spaces

YAML forbids tabs. If your editor inserts a tab character instead of spaces, the YAML parser will throw an error on that line. Most editors auto-convert tabs to spaces when the file extension is .yaml or .yml, but it's worth checking before you commit.

Set your editor to:

  • Insert spaces when pressing Tab
  • Tab size: 2 (most YAML ecosystems standardize on 2-space indentation)

Kubernetes, Docker Compose, and GitHub Actions all default to 2-space indentation. Using 4 spaces is technically valid but visually inconsistent with the conventions of the ecosystem, and it makes your files harder for others to edit.

Inconsistent Indentation Width

YAML allows any number of spaces for indentation, but all sibling nodes must use the same indentation width:

# This fails
parent:
    child_a: value      # 4 spaces
  child_b: value        # 2 spaces -- siblings with different indent

Fix: pick an indent width (2 or 4 spaces) and stick with it for the entire file. Don't mix. Most YAML linters have a rule for this. In yamllint, it's indentation: consistent.

Flow Style vs Block Style

YAML has two syntaxes: block style (the indented form you normally see) and flow style (brackets and commas, like JSON). Mixing them creates visual confusion:

# Block style -- clear nesting
containers:
  - name: nginx
    image: nginx:1.25

# Flow style -- compact, harder to indent correctly
containers: [{name: nginx, image: nginx:1.25}]

Flow style inside block style is legal but risky. A flow-style list at the wrong indentation level can produce a valid but broken structure. Prefer block style for readability. Reserve flow style for short, single-line values.

Workflow to Debug YAML

  1. Validate first: open the YAML Validator, paste your file, and let it catch syntax errors before you deploy.
  2. Convert to JSON to compare: open the YAML to JSON Converter. If the JSON output looks wrong structurally, you have an indentation bug. JSON's braces make the actual structure unambiguous.
  3. Check with your orchestration tool: kubectl apply --dry-run=client -f manifest.yaml or docker compose config will surface indentation errors in context before they hit production.
  4. Use an editor with YAML language support: VS Code, IntelliJ, and vim with coc-yaml all highlight indentation problems. The Red Hat YAML extension for VS Code is particularly good at catching structural errors.

Try it yourself: open the YAML Validator. Paste a YAML snippet with deliberately wrong indentation (a child indented 3 spaces instead of 2) and see the error message. Then fix it and compare the valid output. Convert the fixed YAML to JSON with the YAML to JSON Converter to confirm the structure is what you intended.

Related Reading