DevToolBoxFREE
Blog

Docker Compose YAML Validation: 10 Common Syntax Errors and How to Fix Them

9 min readby DevToolBox
Ad Space

Docker Compose YAML files are deceptively simple — until they break. A single misplaced space, a wrong indentation level, or an unquoted special character can produce cryptic error messages. Here are the 10 most common mistakes and exactly how to fix each one.

Validate your YAML with our JSON-YAML Converter →

Error 1: Tabs Instead of Spaces

Error message:

yaml: line 5: found a tab character where an indentation space is expected

Problem: YAML strictly prohibits tab characters for indentation. This is the #1 mistake.

Fix: Replace all tabs with spaces (2 spaces per indent level is standard).

# BAD (tabs - invisible but breaks YAML)
services:
	web:
		image: nginx

# GOOD (2 spaces)
services:
  web:
    image: nginx

Editor tip: Enable "Render Whitespace" in your editor to see the difference between tabs and spaces. In VS Code: Settings → Render Whitespace → "all".

Error 2: Inconsistent Indentation

Error message:

yaml: line 8: mapping values are not allowed in this context

Problem: Mixing different indentation levels (e.g., 2 spaces for some, 4 for others).

# BAD (inconsistent: 2 spaces then 4 spaces)
services:
  web:
      image: nginx     # 4 spaces - inconsistent!
      ports:
        - "80:80"

# GOOD (consistent 2 spaces)
services:
  web:
    image: nginx       # 2 spaces - consistent
    ports:
      - "80:80"

Error 3: Unquoted Special Characters in Values

Error message:

yaml: line 6: did not find expected key

Problem: YAML interprets certain characters specially. Colons, hashes, and braces need quoting.

# BAD
services:
  web:
    environment:
      - DATABASE_URL=postgres://user:pass@db:5432/mydb  # colon in value!
      - APP_TITLE=My App: The Best                       # colon in value!

# GOOD (quote values with special characters)
services:
  web:
    environment:
      - "DATABASE_URL=postgres://user:pass@db:5432/mydb"
      - "APP_TITLE=My App: The Best"

Characters that need quoting: : { } [ ] , & * # ? | - < > = ! % @

Error 4: Wrong Port Mapping Format

Error message:

services.web.ports contains an invalid type, it should be a number, or an object

Problem: Port values that look like base-60 numbers to YAML (e.g., 80:80 without quotes).

# RISKY (YAML may interpret as base-60)
services:
  web:
    ports:
      - 80:80        # Works but risky
      - 5432:5432    # May cause issues

# SAFE (always quote port mappings)
services:
  web:
    ports:
      - "80:80"
      - "5432:5432"
      - "127.0.0.1:3000:3000"

Error 5: Missing or Wrong Version Key

Error message:

(root) Additional property version is not allowed

Problem: Docker Compose v2 (the current version) no longer requires or accepts the version key.

# OUTDATED (Docker Compose v1 format)
version: "3.8"
services:
  web:
    image: nginx

# CURRENT (Docker Compose v2 - no version needed)
services:
  web:
    image: nginx

If you're using docker compose (v2, with a space), remove the version key. If you're using docker-compose (v1, with a hyphen), keep it.

Error 6: Environment Variables as Mapping vs List

Error message:

services.web.environment must be a mapping or an array

Problem: Mixing mapping and list syntax for environment variables.

# Format A: List (with dashes)
services:
  web:
    environment:
      - NODE_ENV=production
      - PORT=3000

# Format B: Mapping (key: value)
services:
  web:
    environment:
      NODE_ENV: production
      PORT: 3000

# BAD: Mixing both formats
services:
  web:
    environment:
      NODE_ENV: production
      - PORT=3000          # ERROR: mixing formats!

Error 7: Boolean Values Not Quoted

Error message: No error, but unexpected behavior.

Problem: YAML interprets yes, no, true, false, on, off as booleans, not strings.

# BAD (YAML converts to boolean true/false)
services:
  web:
    environment:
      FEATURE_FLAG: yes       # becomes boolean true, not string "yes"
      DEBUG: on               # becomes boolean true
      COUNTRY: NO             # becomes boolean false (Norway code!)

# GOOD (quote string values)
services:
  web:
    environment:
      FEATURE_FLAG: "yes"
      DEBUG: "on"
      COUNTRY: "NO"

Error 8: Duplicate Keys

Error message: Often no error — the second value silently overwrites the first.

# BAD (duplicate 'ports' key - second one silently wins)
services:
  web:
    image: nginx
    ports:
      - "80:80"
    environment:
      - NODE_ENV=production
    ports:                    # DUPLICATE! This replaces the first ports
      - "443:443"

# GOOD (combine under single key)
services:
  web:
    image: nginx
    ports:
      - "80:80"
      - "443:443"
    environment:
      - NODE_ENV=production

Error 9: Volumes Path Mapping Issues

Error message:

services.web.volumes contains an invalid type

Problem: Windows paths with backslashes cause issues without proper quoting.

# BAD (Windows paths without quotes)
services:
  web:
    volumes:
      - C:\Users\me\app:/app     # Backslashes cause issues

# GOOD (use forward slashes or quotes)
services:
  web:
    volumes:
      - "./app:/app"
      - "/home/user/data:/data"
      - "C:/Users/me/app:/app"      # Forward slashes on Windows

Error 10: YAML Anchors Used Incorrectly

Error message:

yaml: unknown anchor 'common'

Problem: Referencing an anchor (*name) before defining it (&name).

# BAD (reference before definition)
services:
  web:
    <<: *common          # ERROR: 'common' not defined yet

x-common: &common
  restart: always

# GOOD (define anchor first, then reference)
x-common: &common
  restart: always
  logging:
    driver: json-file

services:
  web:
    <<: *common
    image: nginx
  api:
    <<: *common
    image: node:20

Quick Validation Checklist

Before running docker compose up, verify:

  1. Run docker compose config to validate syntax
  2. Check for tabs: grep -P '\t' docker-compose.yml
  3. Ensure all port mappings are quoted
  4. Verify no duplicate keys at the same level
  5. Quote all values containing special characters
  6. Use consistent indentation (2 spaces recommended)

Validate your YAML with our JSON-YAML Converter →

Format JSON output from "docker compose config" →

Frequently Asked Questions

How do I validate a Docker Compose file before running it?

Run "docker compose config" (or "docker-compose config" for v1) to validate and display the resolved configuration. This command parses the YAML, resolves variables, and shows any syntax errors. You can also use online YAML validators or our JSON-YAML Converter tool to check syntax.

Why does Docker Compose say "service must be a mapping" or "services must be a mapping"?

This error means your services section (or an individual service) is not properly structured as a YAML mapping (key-value pairs). Common causes: missing indentation under a service name, using a list (-) where a mapping (key:value) is expected, or a typo in the service structure.

Should I use tabs or spaces in Docker Compose YAML files?

Always use spaces. YAML does not allow tabs for indentation — this is the single most common source of YAML parse errors. Configure your editor to insert 2 spaces when you press Tab. Most editors have a "Convert Indentation to Spaces" command.

Try These Related Tools

Y{}JSON ↔ YAML Converter{ }JSON Formatter
Ad Space

Related Articles

Cron Schedule for Serverless: GitHub Actions, Vercel Cron, and Cloudflare Workers

Master cron expressions across serverless platforms. Learn syntax differences, timezone pitfalls, and copy-paste schedule examples.