What this error means
The message yaml: mapping values are not allowed in this context comes from the YAML parser, not Docker Compose itself. It appears when a colon (:) is interpreted as starting a key:value pair where YAML does not expect a mapping. In docker-compose.yml, this most often comes from unquoted colons in strings, bad indentation, or list items that accidentally become mappings.
Minimal working example
This compose file includes a colon safely by quoting or using a list form for command.
author: example
services:
app:
image: alpine:3.19
command: ['sh','-lc','echo hello: world && sleep 1']
Run it:
docker compose up --abort-on-container-exit
If your file fails to parse, start from this minimal example and add sections back gradually.
Quickstart: fix checklist
- Validate the file
- Run: docker compose config
- If it errors, the line number is usually accurate.
- Replace tabs with spaces
- YAML forbids tabs. Use 2 spaces per indent.
- Quote anything with colons
- Strings such as '80:80', './data:/var/lib', 'a: b' must be quoted when ambiguous.
- Fix list items that look like mappings
- A line like '- 80:80' can be read as a mapping. Quote it as '- "80:80"' or '- '80:80''.
- Use proper environment syntax
- Either a mapping or a list of KEY=VAL strings, not a mix.
- Use block scalars for multi-line commands
- command: | line1 with : safely line2
- Re-run docker compose config after each change.
Common causes and fixes
1) Unquoted colon in strings (command, args, labels, env)
Incorrect:
services:
app:
image: alpine
command: sh -lc echo hello: world
Correct (quote or use list):
services:
app:
image: alpine
command: ['sh','-lc','echo hello: world']
Or use a block scalar:
services:
app:
image: alpine
command: |
sh -lc "echo hello: world"
2) Ports lines interpreted as mappings
Incorrect (space after colon creates a key:value pair):
services:
app:
image: nginx
ports:
- 8080: 80
Correct (quote the pair or remove the space):
services:
app:
image: nginx
ports:
- '8080:80'
3) Volume mounts with options and drive letters
Incorrect:
services:
db:
image: postgres
volumes:
- ./data:/var/lib/postgresql/data: rw
- C:\code:/app
Correct:
services:
db:
image: postgres
volumes:
- './data:/var/lib/postgresql/data:rw'
- 'C:\\code:/app'
Notes:
- Keep the mount as a single string when colons are present.
- On Windows, escape backslashes in YAML or use forward slashes in WSL paths.
4) Environment section mixed styles
Incorrect (list of mappings; also prone to colon issues in values):
services:
api:
image: node
environment:
- NODE_ENV: production
- URL: http://localhost:8080
Correct (use mapping form):
services:
api:
image: node
environment:
NODE_ENV: production
URL: 'http://localhost:8080'
Or list of KEY=VAL strings:
services:
api:
image: node
environment:
- NODE_ENV=production
- URL=http://localhost:8080
5) Variable interpolation with colons
Incorrect (unquoted default containing a colon):
services:
web:
image: nginx
command: sh -lc echo ${MSG:-hello: world}
Correct (quote or block scalar):
services:
web:
image: nginx
command: ['sh','-lc','echo ${MSG:-hello: world}']
6) Tabs, indentation, and trailing colons
Incorrect:
services:
app:
image: alpine
command:
Correct:
services:
app:
image: alpine
command: ['sh','-lc','echo ok']
Rule of thumb:
- Use spaces, not tabs.
- Do not leave a key ending with a colon without a value on the same line unless the next indented block provides it.
Validation commands
- Check parsing and normalized config:
docker compose config
- Lint YAML (if you have a linter):
yamllint docker-compose.yml
- Find and replace tabs with spaces in a Unix shell:
sed -i.bak $'s/\t/ /g' docker-compose.yml
Pitfalls to avoid
- Leaving spaces around colons in list items, e.g., '- 8080: 80'.
- Mixing environment mapping and list styles under the same key.
- Forgetting to quote URLs, labels, or headers that contain colons.
- Splitting a single mount across multiple YAML tokens; keep it one string.
- Using tabs for indentation.
- Accidentally adding a colon in an inline comment that is not quoted.
Performance notes
- Use docker compose config before up to fail fast; parsing errors stop early.
- Large files parse linearly; shorter, modular files are quicker to validate.
- Quoting has no runtime cost; it only affects parsing clarity.
- Reduce duplication with YAML anchors and aliases to keep the file small and readable, which makes mistakes less likely and debugging faster.
Tiny FAQ
Q: Why does '- 80:80' sometimes fail?
- A: YAML may read it as a mapping entry. Quote it as a string: '- '80:80''.
Q: Do I need to quote every colon?
- A: Only when it can be misread as key:value, especially in list items or plain scalars.
Q: Is the error specific to Docker Compose?
- A: No, it is a YAML syntax error. Compose just reports the parser failure.
Q: Can I omit the version key?
- A: Yes with the Compose spec, but still follow valid YAML rules.
Q: How do I find the bad line fast?
- A: Run 'docker compose config'. If unclear, bisect the file by commenting out halves until the error disappears.