The other pages of this reference describe YAML 1.2.2, and say where 1.1 reads a file differently. This page covers the syntax of the older versions, so that every version of the format that has a published specification is described: 1.0 (2004), 1.1 (2005) and 1.2 (2009, with revisions 1.2.1 and 1.2.2 that change the wording and not the language). The 1.0 text is at yaml.org/spec/1.0 and is marked as a draft in places: it has a few unfinished notes of its own, written TODO.
The syntax of each version
| Part | YAML 1.0 | YAML 1.1 | YAML 1.2 |
|---|---|---|---|
| Directives | Only YAML is defined. Written %YAML:1.0, name and value joined by a colon, after the --- on the document’s header line | %YAML 1.1 and %TAG, on lines of their own before --- | As 1.1 |
| Unknown directives | Ignored with a warning; no private directives | Ignored with a warning | Ignored with a warning |
| Version rule | A 1.0 processor accepts a 1.0 or missing directive, warns for a higher minor version and rejects a higher major version | The same rule for 1.1 | The same rule for 1.2 |
| Tag shorthands | !str is tag:yaml.org,2002:str; !!ball is the private tag tag:private.yaml.org,2002:ball; !word/name is in the vocabulary domain; !domain.tld,2002/name is tag:domain.tld,2002:name | !!str is tag:yaml.org,2002:str; !local; !e!name with a %TAG; !<verbatim> | As 1.1 |
| Tag prefix | !domain.tld,2002/^invoice sets a prefix that a descendant’s !^customer reuses | Replaced by %TAG | As 1.1 |
| Full tag URIs in the file | Not allowed: only shorthands | Allowed as !<…> | Allowed as !<…> |
| Types | Three tags must be supported: seq, map and str. Other types come from a separate tag repository; a plain scalar is typed by its form (the specification’s example reads n as false) | The type repository, with its regular expressions | Schemas: failsafe, JSON and core |
Merge key << | Not in the specification. The list of types it points to (the 2004 version of the tag repository) already has !merge | In the type repository as !!merge | Not in a schema; supported as an extension by many readers |
Escape \^ | Defined (a circumflex) | Not in the list | Not in the list |
Escape \/ | Not defined | Not defined | Defined, for JSON |
| Other escapes | \\ \" \a \b \e \f \n \r \t \v \0 \_ \N \L \P, backslash and space, and \x \u \U with 2, 4 and 8 hexadecimal digits | The same | The same, with \/ and backslash and tab |
| Encodings | UTF-8 and UTF-16, found by the byte order mark, UTF-8 without one | UTF-8 and UTF-16. UTF-32 is explicitly not supported | UTF-8, UTF-16 and UTF-32, also found by the pattern of zero bytes |
| Line breaks | LF, CR, CR LF and NEL are generic line breaks; LS and PS are line breaks with a meaning of their own | The same | LF, CR and CR LF only. NEL, LS and PS are ordinary characters |
| Comments | Called throwaway comments: # to the end of the line | Comments | Comments, which need white space before the # |
First document without --- | Must be a collection | — | Can be any node |
| JSON | Not a goal | Not a goal | Every JSON text is YAML |
| Block scalars | | and >, chomping - and +, an indentation digit; the two indicators in either order | The same | The same |
| Repeated keys | An error; a processor may go on, ignoring the second key, with a warning | An error | An error |
| Indentation | Spaces only. A node is indented further than its parent; siblings line up. A block sequence under a mapping key need not be indented (the - counts as indentation); a sequence inside a sequence must be | Spaces only; the same rule for sequences | Spaces only; the same rule for sequences |
| Compact forms | A block collection can start on the line of the parent’s - or ? when neither it nor its first entry has properties; the indicator and the spaces after it count as indentation | Present | Present |
| Tabs | Not allowed in indentation. A tab is white space (s-char is tab or space) between tokens | Not allowed in indentation | Not allowed in indentation; a tab can separate tokens and can follow the indentation in front of a scalar |
| Document markers | --- followed by a line break or spaces starts a document and is required between documents; ... ends one, and only comments can follow it before the next ---. A non-indented line that starts with either is never content | The same; such a line is forbidden as content | The same; such a line is forbidden as content |
| Plain scalars: first character | Not an indicator, except -, ?, : and , when a non-space plain character follows | Not an indicator, except -, ? and : when a non-space character follows | The same as 1.1 (a flow indicator cannot follow in a flow collection) |
| Plain scalars: inside | Three contexts. At the top level anything except : and a space (: ) or a space and #. In a flow collection also none of [ ] { }, and a comma only when a non-space character follows it. As a key: the flow rules, on one line | Outside a flow collection as 1.0’s top level. Inside one, none of , [ ] { }. A key must be on one line | As 1.1; : ends a plain scalar when white space (or, in a flow collection, a flow indicator) follows |
| Implicit keys | Plain keys on one line. No length limit is stated | One line, at most 1024 characters | One line, at most 1024 characters |
| Flow sequences and mappings | Entries separated by a comma that must be followed by white space or a line break; no trailing comma. A mapping entry’s : must be followed by white space; a key without : has a null value. A single key: value pair is allowed in a sequence. No ? in flow style | A comma need not be followed by white space; the last entry may have a trailing comma | The same as 1.1; ? explicit keys are allowed, and a : directly after a quoted key needs no space |
| Anchor and alias names | One or more of any non-space characters | One or more of any non-space characters | Any non-space character except the flow indicators , [ ] { } |
| Line breaks inside scalars | CR LF, CR and NEL become one line feed; LS and PS are kept | The same | CR LF and CR become one line feed; NEL, LS and PS are ordinary characters |
Anchors, aliases, ? keys, flow and block collections | Present, with the same meaning | Present | Present |
The cells for 1.0 are from the 1.0 specification, the cells for 1.1 from the 1.1 specification, and the cells for 1.2 from the 1.2.2 specification and this site’s other pages. A dash means the text read for this page does not say.
The ^ tag prefix of YAML 1.0
A tag in YAML 1.0 can set a prefix for the tags of the nodes below it, so that a document whose nodes all have long tags from one domain does not repeat the domain (section 4.3.5.3 of the specification):
- A tag of the form
!prefix^suffixis the tag!prefixsuffix: the^is dropped. The node also setsprefixfor its descendants. - A tag of the form
!^suffixon a descendant is written as!prefixsuffix, with the prefix of the nearest ancestor that set one. - A
^that is part of a tag is escaped with a backslash. - The mechanism is syntax only: the prefix has no meaning of its own.
--- %YAML:1.0
invoice: !domain.tld,2002/^invoice # the tag domain.tld,2002/invoice; sets the prefix domain.tld,2002/
customers: !seq
- !^customer # the tag domain.tld,2002/customer
given: Chris
Two things are errors:
- A tag with more than one unescaped
^, such as!domain.tld,2002/^in^voice. - A tag that starts with
^on a node that has no ancestor with a prefix, such as!^customerat the top of a document, or under a node whose tag had no^.
The prefix reaches only the nodes below the node that set it. A later sibling does not inherit it, and a nearer ancestor’s prefix replaces a farther one. The file viewer applies the mechanism and reports both errors.
Value forms: YAML 1.0 and 1.1 against 1.2
The 1.0 specification names three tags that every processor must support (seq,
map and str) and leaves the other types to a separate list. The
2004 version of that list, saved by the Internet Archive, names !omap,
!pairs, !set, !binary, !bool, !float, !int,
!merge, !null, !yaml, !timestamp and !value. The pages for each
type survive only as the working drafts of December 2004 and January 2005 (the 1.1
type repository), so those are the value forms that the viewer applies to a 1.0
document, as it does to a 1.1 document. The forms in the repository’s regular expressions:
| Type | YAML 1.0 and 1.1 repository (a plain scalar matching) | YAML 1.2 core schema |
|---|---|---|
| null | ~, null, Null, NULL, or empty | The same |
| bool | y Y yes Yes YES n N no No NO true True TRUE false False FALSE on On ON off Off OFF | true True TRUE false False FALSE |
| int | [-+]?0b[0-1_]+ (binary), [-+]?0[0-7_]+ (octal), [-+]?(0|[1-9][0-9_]*) (decimal), [-+]?0x[0-9a-fA-F_]+ (hexadecimal), [-+]?[1-9][0-9_]*(:[0-5]?[0-9])+ (base 60); underscores are ignored | [-+]?[0-9]+, 0o[0-7]+, 0x[0-9a-fA-F]+; no underscores |
| float | [-+]?([0-9][0-9_]*)?\.[0-9.]*([eE][-+][0-9]+)?, base 60 with a fraction [-+]?[0-9][0-9_]*(:[0-5]?[0-9])+\.[0-9_]*, [-+]?\.(inf|Inf|INF), \.(nan|NaN|NAN); the exponent needs a sign | [-+]?(\.[0-9]+|[0-9]+(\.[0-9]*)?)([eE][-+]?[0-9]+)?, .inf forms and .nan forms; the exponent’s sign is optional and no dot is needed |
| timestamp | YYYY-MM-DD, or year, one or two digit month and day, T, t or white space, hh:mm:ss with an optional fraction and a zone that is white space and Z or a signed offset [-+]h[h][:mm] | None: a string |
| merge | The key << | None: a string |
| value | The key = | None: a string |
| yaml | !, & and *, the indicators that encode YAML’s own structure | None |
The viewer’s octal form accepts digits 0 to 7 as the current type page does; the
January 2005 draft saved by the Internet Archive printed [0-8_], a typo that was
corrected. The viewer also reads the fraction of a base 10 float as digits and
underscores only, where the repository’s expression lets dots in (so a version number
such as 1.2.3 would match it); readers differ on this, and the viewer treats it as a string.
A 1.0 document
--- %YAML:1.0
- !str 12 # a string, not the integer 12
- !int 12
- !!ball { number: 8 } # the private tag tag:private.yaml.org,2002:ball
- "a\^b" # \^ is a 1.0 escape
- n # false, by the 1.0 specification’s example
--- on the header lineA 1.1 or 1.2 reader treats --- %YAML:1.0 as an error: after --- a
% cannot start a plain scalar.
What the file viewer does for each version
- A document is read as 1.0 or 1.1 only when it says so:
%YAML 1.0or%YAML 1.1on a line before the---, or%YAML:1.0on its own line or after the---. Every other document, with no directive or with%YAML 1.2, is read as 1.2. - A 1.0 or 1.1 document uses the 1.1 type repository for plain scalars (1.0 has no schema of its own), and reads NEL (U+0085), LS (U+2028) and PS (U+2029) as line breaks. In a 1.2 document they are ordinary characters.
- A 1.0 document expands
!str,!!ball,!domain.tld,2002/nameand!word/nameas the table says, accepts\^, applies the^tag prefix and reports its two errors. A stream that declares%YAML:1.0and whose first document has no---line must start with a collection, or the viewer reports an error; a stream that does not declare 1.0 cannot be told to be 1.0, so the rule is not applied to it. - In a 1.0 or 1.1 document an anchor or alias name can hold any character but white
space, so
&a,bis a name. Inside a flow collection the viewer still ends a name at a flow indicator, as libyaml does, so[&a x, *a]reads as it looks. - Every version is parsed by one reader, and the version changes only the things in this table that differ.
Specification
YAML 1.0: yaml.org/spec/1.0, chapter 4 for the syntax and appendix A for the three required tags. YAML 1.1: yaml.org/spec/1.1, chapters 5 to 9. YAML 1.2.2: yaml.org/spec/1.2.2.