alltools.one
YAMLβ€’
2025-06-28
β€’
7 min
β€’
alltools.one Team
YAMLLintingCI/CDDevOpsConfiguration

YAML Linting Best Practices: Catch Errors Before Deploy

A misplaced space in a YAML file can bring down a production deployment. Unlike JSON, which fails loudly on syntax errors, YAML can silently parse incorrect indentation into unexpected data structures. Linting catches these issues before they reach production.

Why Lint YAML?

YAML's flexibility is both its strength and weakness:

# This is valid YAML but probably wrong
ports:
  - 80
  - 443
  name: webserver  # This is a key in the SECOND list item, not the mapping!

The above creates a list where the second item is a mapping {443: null, name: webserver}. A linter would catch this indentation issue. Without linting, this kind of bug can take hours to diagnose.

yamllint: The Standard Linter

yamllint is the most widely used YAML linter. It checks both syntax validity and style consistency.

Installation

pip install yamllint

Basic Usage

# Lint a single file
yamllint config.yaml

# Lint a directory
yamllint .

# Lint with a specific config
yamllint -c .yamllint.yml .

Configuration

Create .yamllint.yml in your project root:

extends: default

rules:
  line-length:
    max: 120
    level: warning
  indentation:
    spaces: 2
    indent-sequences: true
  truthy:
    allowed-values: ['true', 'false', 'yes', 'no']
  comments:
    require-starting-space: true
    min-spaces-from-content: 2
  document-start: disable
  empty-lines:
    max: 1

Key Rules Explained

RulePurposeRecommended Setting
indentationEnforce consistent indentation2 spaces, no tabs
line-lengthPrevent overly long lines120 chars (warning)
truthyControl boolean valuestrue/false only
commentsComment formattingRequire space after #
document-startRequire --- at startDisable (optional)
trailing-spacesNo trailing whitespaceEnable
new-line-at-end-of-fileConsistent file endingsEnable

Common Errors Caught by Linting

1. Tab Characters

YAML forbids tabs for indentation, but editors sometimes insert them:

# ERROR: tab character
server:
port: 8080  # Tab instead of spaces!

2. Inconsistent Indentation

# ERROR: mixing 2 and 4 space indentation
database:
  host: localhost
    port: 5432  # Wrong: 4 spaces instead of 2

3. Duplicate Keys

# ERROR: duplicate key (second silently overrides first)
server:
  port: 8080
  host: localhost
  port: 9090  # Duplicate! Which port is used?

4. Trailing Spaces

Invisible trailing spaces can cause surprising behavior, especially in multiline strings. A linter flags these immediately.

Quick validation without installing anything: paste your YAML into our YAML Validator.

CI/CD Integration

GitHub Actions

name: YAML Lint
on: [push, pull_request]

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install yamllint
        run: pip install yamllint
      - name: Lint YAML files
        run: yamllint .

Pre-commit Hook

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/adrienverge/yamllint
    rev: v1.33.0
    hooks:
      - id: yamllint
        args: [-c, .yamllint.yml]
pip install pre-commit
pre-commit install

Now YAML is automatically linted before every commit.

GitLab CI

yaml-lint:
  image: python:3.12-slim
  script:
    - pip install yamllint
    - yamllint .
  rules:
    - changes:
        - "**/*.yaml"
        - "**/*.yml"

Editor Integration

Most editors support real-time YAML linting:

  • VS Code: Install the "YAML" extension by Red Hat (uses yamllint)
  • Vim/Neovim: Use ALE or coc-yaml
  • JetBrains IDEs: Built-in YAML support with configurable inspections

Enable format-on-save for YAML files to automatically fix whitespace issues.

Tool-Specific Linting

Generic YAML linting catches syntax errors, but tool-specific linters validate semantic correctness:

Kubernetes

# kubeval - validate against K8s schemas
kubeval deployment.yaml

# kubeconform - faster alternative
kubeconform -strict deployment.yaml

Docker Compose

docker compose config --quiet

GitHub Actions

# actionlint - validates workflow syntax
actionlint .github/workflows/*.yml

Ansible

ansible-lint playbook.yml

For a deeper understanding of YAML syntax rules, see our YAML syntax tutorial.

Best Practices Summary

  1. Add yamllint to CI β€” Every YAML change should pass linting
  2. Use pre-commit hooks β€” Catch errors before they reach the repository
  3. Standardize on 2-space indentation β€” The DevOps convention
  4. Disable the truthy rule or restrict it β€” The yes/no boolean problem causes real bugs
  5. Set a reasonable line length β€” 120 characters covers most cases
  6. Use tool-specific validators β€” Generic linting plus K8s/Docker/Actions-specific validation
  7. Configure your editor β€” Real-time feedback is faster than CI failures

FAQ

Should I use YAML or JSON for configuration files?

YAML is preferred for human-edited configuration files due to its readability, comment support, and concise syntax. JSON is better for machine-generated data and API communication. For a detailed comparison, see our YAML vs JSON guide.

How do I handle yamllint warnings vs errors?

Configure critical rules (indentation, syntax) as errors that block CI. Set style rules (line-length, comments) as warnings that appear but don't block. This balances strictness with developer productivity.

Related Resources

Published on 2025-06-28
YAML Linting Best Practices: Catch Errors Before Deploy | alltools.one