Cloud Parts

YAML

The indentation-based text format behind most cloud configuration: Kubernetes manifests, CI workflows and Compose files.

What it is
File formats (text and markup)
Type
Open source
Made by
YAML Language Development Team (open specification at yaml.org)
License
Open specification, free to implement; the spec may be freely copied unmodified
Facts checked
6 October 2026

What it is

YAML describes the same data as JSON (mappings, sequences and scalars), but structure comes from indentation and - list markers instead of brackets. Indentation must be spaces; the spec forbids tabs there. Files can carry # comments, multi-line strings and several documents separated by ---. Unquoted values are typed by pattern matching: in YAML 1.2’s recommended core schema, true and false are booleans, null and ~ are null, things that look like numbers are numbers, and everything else is a string. An anchor (&base) names a node and an alias (*base) repeats it, and tags such as !!str or !!binary set a type explicitly. Since 1.2, every JSON document is also valid YAML.

The spec lives at yaml.org. The current text is revision 1.2.2 (October 2021), which made no normative changes to YAML 1.2 from 2009. Parsers don’t all follow it: PyYAML, Python’s widely used library, implements YAML 1.1 from 2005, where yes, no, on and off are booleans and 22:22 is a base-60 integer. There is nothing to buy; YAML is simply the configuration language of Kubernetes manifests, GitHub Actions workflows, Docker Compose files and the Prometheus config file.

Why teams pick it

  • Easy for people to read and edit, with comments and clean multi-line strings, which is why so much configuration uses it
  • A superset of JSON since 1.2, so tools such as Kubernetes accept either format
  • Anchors and aliases remove repetition, and one file can hold several documents
  • The default for Kubernetes, GitHub Actions, Compose and Prometheus, so one skill covers many tools

Watch out for

  • Unquoted values get guessed types: under YAML 1.1 rules NO (Norway’s country code) becomes false and 22:22 becomes 1342, and 3.10 is the float 3.1 in any version; quote strings to be safe
  • Indentation is syntax: one misplaced space silently moves a key to a different parent instead of causing an error
  • Loaders that honour language tags can run code: PyYAML’s yaml.load could call any Python function before 5.1, so use safe_load for anything untrusted
  • Aliases can make a small file expand into a huge structure; the Kubernetes API server’s CVE-2019-11253 was fixed by capping request size and go-yaml’s alias expansion
  • A long spec with versions that disagree, so the same file can load differently in different parsers

Alternatives

What all text and markup have in common →

How it fits with other technologies

The Norway problem: PyYAML applies YAML 1.1 typing rules · python

# pip install pyyaml
import yaml

doc = """
country: NO        # Norway's ISO code
python: 3.10
ports:
  - 22:22
enabled: on
quoted: "NO"
"""
print(yaml.safe_load(doc))
# {'country': False, 'python': 3.1, 'ports': [1342], 'enabled': True, 'quoted': 'NO'}

# since PyYAML 6.0, yaml.load() needs an explicit Loader
yaml.load("a: 1")  # TypeError: load() missing 1 required positional argument: 'Loader'

# safe_load refuses tags that construct arbitrary Python objects
yaml.safe_load("!!python/object/new:os.system [echo pwned]")  # ConstructorError

JSON, YAML, TOML and XML side by side#

Four text formats for structured data. They overlap, but each grew up around a different job, and that shows in what they leave out.

JSONYAMLTOMLXML
Current specRFC 8259 and ECMA-404 (both December 2017)YAML 1.2.2 (October 2021), a revision of 1.2 from 2009TOML 1.1.0 (December 2025)W3C XML 1.0, Fifth Edition (November 2008)
CommentsNone# to the end of the line# to the end of the line<!-- … -->
Built-in value typesString, number, boolean, nullNull, boolean, integer, float and string in the recommended core schema; others through tagsString, integer, float, boolean, offset and local date-times, dates and timesNone: content is text until a schema gives it types
NestingObjects and arraysMappings and sequences; anchors and aliases reuse a nodeTables, arrays, inline tables and arrays of tablesElements with attributes; namespaces mix vocabularies
Schema languageJSON Schema, a separate spec (latest 2020-12)None; the spec’s “schemas” only decide how unquoted values are typedNone in the specDTDs (part of XML 1.0), W3C XML Schema (XSD), RELAX NG
Typical useWeb API bodies; JSON Lines logs and eventsKubernetes manifests, GitHub Actions workflows, Compose filesCargo.toml, pyproject.toml, Telegraf configOffice documents, SVG, RSS and Atom feeds, SOAP, the S3 API
  • Each cell is taken from the format’s own specification, and typical uses from the documentation of the tools named. The same table appears on the JSON, YAML, TOML and XML pages.

See it in a real stack

No architecture uses YAML yet. Drop it into the playground and wire it up yourself.Open playground →
Where it came from2001–2021

Around 2001, Clark Evans and Oren Ben-Kiki were on the SML-DEV mailing list, which was trying to simplify XML, and Ingy döt Net had written a plain-text serialization module for Perl. Together they designed a data language for people first: readability heads their ranked list of goals, with matching the native data structures of dynamic languages third. The first YAML framework was written in Perl in 2001, Ruby shipped one in its core distribution in 2003, and after three years of design work on the yaml-core list, YAML 1.0 was published in January 2004.

YAML 1.1 followed in 2005, with generous implicit typing that read yes, no, on and off as booleans. Around then the authors noticed that JSON was, by coincidence, almost a subset of YAML. Kyrylo Simonov released PyYAML and LibYAML in 2006, and many other libraries built on them. YAML 1.2 (2009) made YAML a strict superset of JSON and dropped many of the problematic typing rules, but PyYAML, which many other libraries had used as a reference, still implements 1.1. A new design team began meeting in 2020 and published revision 1.2.2 in October 2021.

Why it’s built this way

Indentation instead of brackets
Human readability was the first design goal. Tabs are banned from indentation because different systems treat tabs differently.
Guess types from unquoted values
YAML wanted to match the native data of dynamic languages without type annotations. In 1.1 the guessing was broad, which caused the Norway problem; 1.2’s core schema narrowed booleans to true and false.
Anchors and aliases
Repeated nodes are written once and referenced, so YAML can serialize shared objects and graphs, not just trees. Naive expansion of aliases later became a denial-of-service vector.
Tags for language-specific types
To be expressive and extensible, a tag can name any type. Libraries such as PyYAML used tags to rebuild arbitrary objects, which is why their default loaders were unsafe for untrusted input.

Timeline

  1. 2001

    Design starts on yaml-core; the first YAML framework is written in Perl

  2. 2004

    YAML 1.0 published (January)

  3. 2005

    YAML 1.1, with yes/no and on/off booleans

  4. 2006

    Kyrylo Simonov releases PyYAML and LibYAML

  5. 2009

    YAML 1.2 makes YAML a strict superset of JSON

  6. 2019

    go-yaml caps alias expansion after a Kubernetes API server DoS

  7. 2021

    Revision 1.2.2 (October); PyYAML 6.0 requires an explicit loader

Sources33 · facts checked 6 October 2026

Improve this page on GitHub