yaml.scanner.ScannerError: mapping values are not allowed here (tested)
yaml.scanner.ScannerError: mapping values are not allowed here is one of the most-searched YAML errors, and the wording is confusing — your file probably already is a mapping. We reproduced it two different ways with PyYAML 6.0.3 and found the real cause both times is the same thing: an unquoted colon (:) somewhere YAML doesn't expect one.
1. Cause: a colon inside a plain (unquoted) scalar value
We parsed a value that itself contains a colon, written without quotes:
key: value : extra
yaml.scanner.ScannerError: mapping values are not allowed here
in "<unicode string>", line 1, column 12:
key: value : extra
^
Why: YAML uses key: value (colon-space) as its mapping syntax. The parser reads key: value as one complete key/value pair, then hits a second bare : and interprets it as the start of another mapping entry — but a plain scalar can't contain a nested mapping, so it fails right there. This is exactly what happens with real-world values like a URL (http://example.com), a time (12:30), or a Windows path (C:\Users) written unquoted after a key.
The fix we confirmed: quote any value that contains a colon.
key: "value : extra" # parses as the single string "value : extra"
2. Cause: inconsistent indentation makes a nested value look like a new mapping
We also hit the identical error from bad indentation, with no colon-in-value involved at all:
a:
b: 1
c: 2
yaml.scanner.ScannerError: mapping values are not allowed here
in "<unicode string>", line 3, column 5:
c: 2
^
Why: c: 2 is indented one space deeper than its sibling b: 1 (3 spaces vs 2), so the parser doesn't read it as a second key in the same mapping as b. It instead tries to read c as part of b's own value, then finds a colon where it expected plain scalar content — the same underlying "colon in the wrong place" failure as cause 1, just produced by misaligned indentation instead of an unquoted value. The fix is to align sibling keys to the exact same indentation (here, both at 2 spaces).
3. Two related errors we measured in the same pass
A tab character in indentation fails differently — and earlier, during tokenizing rather than parsing:
a:
b: 1
yaml.scanner.ScannerError: while scanning for the next token
found character '\t' that cannot start any token
in "<unicode string>", line 2, column 1:
b: 1
^
The YAML spec forbids tabs for indentation entirely (spaces only) — this is not PyYAML being strict, every spec-compliant parser rejects it. Fix: replace leading tabs with spaces.
A missing space after the key's colon produces a third, distinct message:
key1: value1
key2:value2
yaml.scanner.ScannerError: while scanning a simple key
could not find expected ':'
Here key2:value2 has no space after the colon, so YAML reads the whole thing as one scalar (not a key at all) and then can't find the mapping colon it expected on the next line. Fix: always put a space after the key's colon (key2: value2).
4. Does js-yaml (Node.js) give the same message?
No — we ran the identical bad-indentation input through js-yaml 4.x on Node.js v24.21.0 and got different wording for the same root cause:
YAMLException: bad indentation of a mapping entry (4:5)
Same underlying problem (misaligned sibling keys), different parser, different error text. If you're searching for your exact message and not finding this page's wording, check which YAML library/language threw it — PyYAML, js-yaml, Ruby's Psych, and Java's SnakeYAML each phrase these failures differently even though the YAML spec they're enforcing is the same.
5. A silent gotcha we found while testing: PyYAML does NOT error on duplicate keys
We expected a: 1\na: 2 (the same key twice) to raise an error. It didn't — yaml.safe_load returned {'a': 2} with no warning, silently keeping the last value and discarding the first. If you need duplicate keys caught, PyYAML's loader won't do it for you; a schema validator or a linter like yamllint (which does flag duplicate keys by default) is the tool for that, not the parser itself.
Frequently asked questions
Why does YAML say 'mapping values are not allowed here' when my file is already a mapping?
The message refers to where YAML encountered an unexpected colon, not to your overall document structure. We confirmed the two real causes: an unquoted value that itself contains a colon (like a URL, time, or Windows path), or sibling keys indented inconsistently so a nested value gets misread as a second colon in the wrong place.
How do I fix 'mapping values are not allowed here' caused by a colon in my value?
Quote the value: key: "value: with a colon" instead of key: value: with a colon. We confirmed PyYAML parses the quoted form as a single string with no error, while the identical unquoted text fails immediately at the second colon.
My indentation looks right but I still get this error — what am I missing?
Count spaces exactly; YAML has no tolerance for sibling keys at different indentation levels, even by one space. We reproduced the error with b: at 2 spaces and c: at 3 spaces under the same parent — visually similar but not byte-identical indentation. Use a YAML-aware editor or linter (yamllint) to catch this instead of eyeballing it.
Can I use tabs for YAML indentation if I'm careful about spacing?
No — we confirmed PyYAML rejects any tab character in indentation outright with 'found character \'\t\' that cannot start any token', regardless of consistency. This isn't a PyYAML-specific restriction; the YAML spec itself forbids tabs for indentation in every compliant parser. Convert tabs to spaces.
Does PyYAML warn me if my file has the same key twice?
No — we tested this directly and PyYAML's safe_load silently resolves a: 1 / a: 2 (same key) to {'a': 2}, keeping the last occurrence with zero error or warning. If duplicate keys are a bug you want caught, use a linter like yamllint, which does flag them by default, rather than relying on the parser.
Written with AI assistance. Measured on 2026-10-03 with PyYAML 6.0.3 on Python 3.13 (yaml.safe_load), and separately with js-yaml 4.x on Node.js v24.21.0 for comparison. Every message and line:column below is copy-pasted output, not paraphrased. PlainHeaders is our extension; PyYAML/js-yaml are free.