What is yaml
Yaml is a well-known data serialization language designed for human readability. It’s a popular choice for configuration files and metadata. Here’s a simple example:
# project.yaml
title: Nonoverse
description: Beautiful puzzle game about nonograms.
link: https://lab174.com/nonoverse
countries:
- DE
- FR
- PL
- ROLet’s verify that the above example parses correctly.
We’ll use Python with PyYaml version 6.0.3 (the latest version as of this writing). First, let’s install it:
python3 -m pip install pyyaml==6.0.3Now let’s write a simple script to parse the yaml file:
# python-pyyaml.py
import json
import yaml
with open("project.yaml", "r", encoding="utf-8") as f:
data = yaml.safe_load(f)
print(json.dumps(data, indent=2))Running python3 python-pyyaml.py produces this
output:
{
"title": "Nonoverse",
"description": "Beautiful puzzle game about nonograms.",
"link": "https://lab174.com/nonoverse",
"countries": [
"DE",
"FR",
"PL",
"RO"
]
}So far everything behaves as expected.
The Norway problem in yaml
When we change the original yaml file and add Norway’s two letter iso country code to the existing list:
countries:
- DE
- FR
- NO
- PL
- ROUsing the same parsing method, the file now yields this result:
{
"title": "Nonoverse",
"description": "Beautiful puzzle game about nonograms.",
"link": "https://lab174.com/nonoverse",
"countries": [
"DE",
"FR",
false,
"PL",
"RO"
]
}Note that NO has been replaced with false.
This is unexpected. Nothing about the context suggests a boolean should
appear here. The NO literal sits in a list of country codes
like FR or PL and appears similar in form. The
problem, of course, is that “no” is also an English word with a negative
meaning.
This feature was originally added to allow writing booleans in a more human readable way, e.g.:
platforms:
iPhone: yes
iPad: yes
AppleWatch: noThis gets parsed as:
{
"platforms": {
"iPhone": true,
"iPad": true,
"AppleWatch": false
}
}The idea was that configuration files should read like natural language. In practice this behavior proved problematic, becoming the notorious Norway problem in yaml.
One workaround is to escape the string, like this:
countries:
- DE
- FR
- "NO"
- PL
- ROWith quotes, the file parses as expected:
{
"title": "Nonoverse",
"description": "Beautiful puzzle game about nonograms.",
"link": "https://lab174.com/nonoverse",
"platforms": {
"iPhone": true,
"iPad": true,
"AppleWatch": false
},
"countries": [
"DE",
"FR",
"NO",
"PL",
"RO"
]
}Many articles about yaml’s Norway problem stop here, presenting quoting as the canonical fix. There is more.
Yaml’s history
To understand today’s state of the Norway problem we’ll first look at how yaml evolved.
May 2001 – Yaml first pass specification
At this time, yaml was more of a concept than a finished language. It looked a bit different, though somewhat recognizable. Below is a partial example from the original specification; there are more in the full document, sadly none with boolean values.
buyer : %
address : %
city : Royal Oak
line one : 458 Wittigen's Way
line two : Suite 292
postal : 48046
state : MI
family name : Dumars
given name : ChrisThe document makes no mention of parsing no to
false. The “Serilization Format / bnf” section even contains a typo and a “to do”
note:
This section contains the bnf productions for the yaml syntax. Much to do…
January 2004 – Yaml v1.0 final draft
This version describes various ways of presenting scalars, including both quoted scalars and plain scalars with implicit typing. This is what we’re after.
Version 1.0 defined only sequence, map, and
string as mandatory types.
The rest were optional, but a reference specification existed. That
reference specification for the optional boolean type included English
word format. Supported words were: true/false,
on/off, and also yes/no.
This allows the Norway problem to appear – even if following that part of reference is described as optional.
– Bonus: implicit typing can be overridden with explicit tags – we’ll talk about this later.
– Bonus: single sign characters, i.e. + and
- should also be treated as true and
false; even more so, as they are described as the canonical
form!
January 2005 – Yaml v1.1 final draft
Version 1.1 maintained the same implicit typing behavior as v1.0. However, the types listed in the spec – including boolean – while still not mandatory, were now strongly recommended.
– Bonus: single sign characters are no longer included and the
canonical form is now y/n.
July 2009 – Yaml Revision 1.2.0
Its goal was to make yaml compliant with json, going as far as allowing json to be a subset of yaml.
Implicit typing rules have been removed, including the boolean English word format.
– Bonus: explicit typing rules are still present.
On paper, the Norway problem shouldn’t exist anymore, at least not since this yaml revision. So why are we still seeing it in 2026?
Yaml spec version history until v1.2.0
| Yaml spec version | Date | Type of no: |
Value of no |
|---|---|---|---|
| first pass specification | May 2001 | unspecified | unspecified |
| v1.0 | January 2004 | boolean | false |
| v1.1 | January 2005 | boolean | false |
| v1.2.0 | July 2009 | string | "no" |
no” and “Value of no”
labels refer to the literal without quotes.
Yaml in practice
To understand why the Norway problem persists, we need to examine the scope of work involved in implementing yaml spec changes. Some clues are present in earlier text already, we see that yaml supports implicit typing, explicit typing, and various presenting formats. Also, the time between different yaml spec version releases is measured in years.
What hides between the lines is that yaml and its specification are very, hugely, extremely complex. Seriously, it’s hard to overstate this.
Since v1.0 yaml’s goal was to build upon xml and a number of other technologies, as listed in the final draft:
Yaml integrates and builds upon concepts described by C, Java, Perl, Python, Ruby, rfc0822 (mail), rfc1866 (html), rfc2045 (mime), rfc2396 (uri), xml, sax and soap
Yaml supports attachments, custom
tags, references – the list goes on. There was even yaxml, an xml
binding for yaml.
There are 9 ways of writing multiline strings – and some claim the
number is actually 63. Characters like ?,
!, !! in some cases have special meanings,
with the latter allowing arbitrary code execution.
Given this complexity, the Norway problem wasn’t the only language quirk in yaml v1.1. Revision v1.2 simplified boolean behavior and more (e.g. handling of null and numerical values), while other language features remained unchanged.
How did libraries react to changes in such a complex specification?
Yaml libraries
As of January 2026 popular yaml libraries still haven’t moved from v1.1 to v1.2, and they still exhibit the Norway problem. Smaller alternative projects have appeared, but their usage hasn’t surpassed the existing v1.1 libraries. Some users have built their own alternative parsers, mixing v1.1 and v1.2 features, or focusing on a subset of yaml suited to their needs.
Below are some examples.
PyYaml
As mentioned before, PyYaml is Python’s most popular yaml library and one of the most popular Python libraries overall.
PyYaml never added v1.2 support.
There is an open issue from 2017 in PyYaml’s Github project about introducing support for v1.2. There are at least two more related open issues, plus several closed ones. An unofficial library exists that can be used on top of PyYaml to provide partial v1.2 support (its documentation notes that not all v1.2 features are implemented). Another Python library, ruamel.yaml, supports v1.2 by default.
LibYaml
LibYaml is the long-standing C library for yaml, it is used widely as a dependency by other tools and bindings. Like PyYaml, it’s an “official” implementation – in the sense that its canonical repository is hosted on Github and owned by the official ‘yaml’ Github account.
LibYaml also never added v1.2 support.
An open issue from 2016 in LibYaml’s github project requests adding v1.2 support. As mentioned earlier, LibYaml sits deep in dependency trees; changing its behavior is especially risky and slow. A less popular library, libfyaml, supports v1.2 by default.
Golang’s gopkg.in/yaml.v3
Currently unmaintained, historically the most popular and still holds more Github stars then other Golang yaml libraries. It’s especially interesting because it declares support for a mix of v1.1 and 1.2. The Golang’s most popular actively maintained library defaults to v1.2 behavior.
Kyaml
Kyaml is a yaml dialect built for the Kubernetes project, launched in June 2025. Its goal is to provide a safer and less ambiguous tool; it is also designed specifically for Kubernetes, trading generality for predictability. The announcement blog post references the Norway problem directly.
Is the Norway problem solved?
Yaml’s ecosystem is not just libraries, it’s also the community of users. Including: strong and conflicting opinions about yaml in general and the Norway problem in particular.
In some part this outcome could be expected; after all yaml is very popular, deceptively complex, and is used in different kinds of scenarios, from small personal config files to critical infrastructure setups.
Many texts don’t distinguish between yaml spec versions at all. Even when spec version numbers are used, they’re frequently mistyped. It’s not difficult to find documentation claiming that implicit boolean typing is a trait of yaml specification version 1.2 (the correct version is v1.1); mistakes get spotted and eventually updated, but that takes more time and effort than making the original typo.
On the other hand we see users who declare the Norway problem as solved because it doesn’t exist in the latest spec version, or because they haven’t experienced it themselves, or for other reasons. To be fair, that language feature was removed over a decade ago, and it’s unexpected that popular libraries still support the older spec version. Technically, the issue is solved in the spec – but in practice, most widely adopted implementations still support implicit boolean typing, as we’ve seen.
Finally, there are end users who are so unhappy with yaml that they prefer almost anything else.
We end up with countless use cases (hobby, pro, critical infrastructure, …), roles (spec author, library maintainer, end user debugging a failed deployment at 11pm, …), and just as many points of views.
What next?
In yaml final draft v1.0, the document
specified that, along with yes and no,
+ and - should also be parsed as booleans.
This was removed v1.1. There was an idea to keep that functionality when
plus or minus signs were preceded with a dot (.+ and
.-), but it didn’t catch on.
Despite its well known and lesser known quirks, yaml remains popular and widely used. At this scale small quirks cascade into unexpected issues. And changes – or fixes – are introduced at a glacial pace.
Then again, yaml’s charm has its place, as evidenced by its popularity. While spec change adoption is very slow, it is still ongoing. New projects will likely adopt newer libraries, where the Norway problem no longer exists.
If there is a single takeaway from this article, it’s this: yaml ecosystem is fragmented; on the whole it is moving towards a slightly stricter version. Implicit boolean typing is getting removed, it’s no longer in the official specification and most new libraries adhere to that. As of January 2026 however, the older libraries are stuck on the older version of the spec, they are still more popular and updating or phasing them out may take a while.
Frequently Asked Questions
Why not just use json in place of yaml?
A common reply is “no comments” – because json doesn’t support comments; many other yaml features aren’t supported either. This makes json a simpler and stricter alternative. Wheter that’s a better fit for your project, that depends on the project. As always, personal preference plays a role too. Note: json has its own flavors, like jsonc.
Is yaml a superset of json?
After writing this article, I’m still not entirely sure. Even though the goal of yaml revision v1.2.0 was to make that happen and revisions 1.2.0 and 1.2.1 claimed it explicitly:
Yaml can therefore be viewed as a natural superset of json, offering improved human readability and a more complete information model.
That text has been removed from the latest yaml revision 1.2.2.
A popular article claims to prove that yaml is not a superset of json, but that article uses a v1.1 parser – and as we know v1.1 never claimed json compatibility. So that won’t help us.
The actual reason might be that yaml requires maps to have unique keys, while json only recommends it. So perhaps most json (i.e. json where objects have unique keys) is a subset of yaml. Some ambiguity remains.
What went wrong?
This question is out of scope for this article – here the goal is to prioritize facts over “what if?”.
If i had to answer, I’d say that nothing went wrong. When a complex technology with a stable ecosystem introduces a breaking change, sometimes the process can take ages. The main surprise here is how complicated yaml really is. Also, as we’ve seen, with yaml and related tools being free software, anyone could contribute to improving the v1.2 adoption rate – or move to a tool that suits them better, or even create one.
What about toml, sexagesimal numbers, schemas, human genes, Ruby, or Perl?
These topics are only loosely related to the Norway problem, and this text is already quite long. If you enjoyed reading it, leave positive feedback somewhere and a Part 2 might happen. In the meantime, visit my homepage and check out my other projects – maybe you’ll find something else you’ll enjoy.
Epilogue
Implicit boolean typing has been removed, but explicit boolean typing still remains. If a uniform yaml 1.2 future actually arrives, you can still bring a little bit of nostalgia to your code by writing:
title: Nonoverse
description: Beautiful puzzle game about nonograms.
link: https://lab174.com/nonoverse
platforms:
iPhone: !!bool yes
iPad: !!bool yes
# Note the explicit typing here and above.
AppleWatch: !!bool no
countries:
- DE
- FR
- NO
- PL
- ROWhen parsed with yq, a tool that supports yaml revision 1.2 by default:
yq eval -o=json project.yaml
It returns:
{
"title": "Nonoverse",
"description": "Beautiful puzzle game about nonograms.",
"link": "https://lab174.com/nonoverse",
"platforms": {
"iPhone": true,
"iPad": true,
"AppleWatch": false
},
"countries": [
"DE",
"FR",
"NO",
"PL",
"RO"
]
}