TL;DR — la sintaxis de YAML en un minuto
- Usa solo espacios (nada de tabuladores). La indentación de 2 espacios es la convención de facto.
key: valuenecesita un espacio después de los dos puntos.key:valuees una sola cadena.- Las listas usan
-(guion + espacio). Los mapeos usankey: value. - Entrecomilla los valores que podrían interpretarse mal como números, booleanos o fechas:
version: "1.0". - Detecta errores rápido pegando el contenido en el validador YAML a JSON de FormatArc: los mensajes con número de línea apuntan directo al problema.
Qué es YAML y dónde lo verás
YAML (YAML Ain't Markup Language) es un formato de texto legible para datos estructurados. Cubre el mismo modelo de datos que JSON (cadenas, números, booleanos, nulos, listas y mapeos), pero su sintaxis se basa en la indentación en lugar de llaves y corchetes.
Si trabajas con herramientas modernas de DevOps o nativas de la nube, ya te has cruzado con YAML:
- Manifiestos de Kubernetes y charts de Helm
- Archivos de Docker Compose
- Flujos de trabajo de GitHub Actions, GitLab CI y CircleCI
- Playbooks de Ansible
- Especificaciones OpenAPI
- Generadores de sitios estáticos (Hugo, Jekyll, Eleventy)
Esta guía recorre cada parte de la sintaxis de YAML que realmente vas a usar, con ejemplos y una lista de los errores que más atrapan a los principiantes. Si quieres comparar YAML con JSON directamente, consulta YAML vs JSON: diferencias clave, o lee la guía paso a paso de cómo convertir YAML a JSON.
Los tres bloques de construcción
Todo en un archivo YAML es una de estas tres cosas:
- Escalar: un único valor como una cadena, un número, un booleano o un nulo
- Secuencia: una lista ordenada de elementos
- Mapeo: un conjunto desordenado de pares clave-valor
Puedes anidarlos libremente. Un mapeo puede contener listas, una lista puede contener mapeos, y ambos pueden contener otros mapeos o listas. Eso es todo lo que necesitas para representar cualquier estructura compatible con JSON.
Reglas de indentación
La indentación es la forma en que YAML expresa el anidamiento. Algunas reglas que conviene interiorizar:
- Usa espacios, nunca tabuladores: un carácter de tabulación literal es un error de sintaxis en la mayoría de los parsers
- Elige un tamaño de indentación (2 espacios es la convención) y mantente coherente
- Todos los elementos del mismo nivel deben tener la misma indentación
- La indentación determina la estructura; no hay delimitador de cierre
Aquí tienes un ejemplo válido sencillo:
database:
host: localhost
port: 5432
credentials:
user: admin
password: secret
database contiene un mapeo, que a su vez contiene host, port y credentials. credentials es un mapeo anidado. La indentación de dos espacios le indica a YAML exactamente cómo encaja la estructura.
Escribir pares clave-valor (mapeos)
Un mapeo se escribe como key: value, con un espacio después de los dos puntos. El espacio es obligatorio: key:value es una sola cadena, no un mapeo.
name: Alice
age: 30
is_admin: true
bio: null
Las claves suelen ser cadenas simples. Pueden contener espacios si se entrecomillan:
"full name": Alice Cooper
Los valores pueden ser cualquier tipo de YAML: escalar, secuencia u otro mapeo.
Escribir listas (secuencias)
Una secuencia es una serie de líneas que comienzan con - (un guion seguido de un espacio).
fruits:
- apple
- banana
- cherry
Las listas pueden contener cualquier tipo de valor, incluidos mapeos anidados:
users:
- name: Alice
role: admin
- name: Bob
role: editor
Cada guion inicia un nuevo elemento de la lista. Los campos que le siguen pertenecen a ese elemento hasta que aparece otro guion al mismo nivel de indentación.
Estilo de bloque y estilo de flujo
Todo lo anterior es estilo de bloque: un elemento por línea, la indentación marca el anidamiento. YAML también tiene una forma en línea (de flujo) que se parece a JSON:
fruits: [apple, banana, cherry]
users: [{name: Alice, role: admin}, {name: Bob, role: editor}]
La forma de flujo resulta práctica para listas pequeñas, pero se vuelve más difícil de leer a medida que crecen los datos. Quédate con la forma de bloque para cualquier cosa que no sea trivial. Si dejas una colección de flujo sin cerrar, cada parser lo reporta de forma distinta: consulta la fila "Flujo [ sin cerrar" en la tabla de mensajes por parser más abajo.
Cadenas: cuándo entrecomillar
La mayoría de las cadenas en YAML se pueden escribir sin comillas.
greeting: Hello, world
Solo necesitas comillas cuando:
- El valor se interpretaría de otro modo como un tipo diferente:
version: "1.0",country: "NO",postal_code: "07030" - El valor empieza con un carácter que YAML lee como estructura:
[,],{,},,,*,|,>,%,@,`,",', o#,&,!. Un-,:o?inicial solo da problemas cuando lo sigue un espacio - El valor contiene dos puntos seguidos de un espacio (lo que de otro modo parecería un mapeo)
- Quieres incluir secuencias de escape como
\no\t
YAML admite comillas simples y dobles. Las comillas dobles interpretan las secuencias de escape; las comillas simples tratan todo de forma literal.
escaped: "line1\nline2"
literal: 'line1\nline2'
Los caracteres que de verdad causan problemas se dividen en dos grupos, y el grupo decide si hacen falta comillas. La tabla siguiente es lo que hace el parser de nuestro propio conversor (yaml (eemeli) 2.8.3, YAML.parse con los valores por defecto; medido el 2026-08-15, script de reproducción en el repositorio, en scripts/benchmarks/yaml-quote-requirements/). Léela así: cuando la columna central dice "seguro", puedes dejar el valor sin comillas siempre que el carácter no vaya al principio.
| Carácter | Al principio del valor | En medio del valor | Basta con comillas simples | Comillas dobles |
|---|---|---|---|---|
[ ] { } , | Error de parseo | Seguro | Sí | También valen |
* | Error de parseo (se lee como alias) | Seguro | Sí | También valen |
& | Sin error: se convierte en ancla y el valor se pierde | Seguro | Sí | También valen |
! | Sin error: se convierte en etiqueta | Seguro | Sí | También valen |
# | Sin error: el valor entero se lee como comentario y queda en null | Seguro salvo que lo preceda un espacio | Sí | También valen |
| > | Error de parseo (se lee como escalar de bloque) | Seguro | Sí | También valen |
% @ ` | Error de parseo (reservados) | Seguro | Sí | También valen |
- ? | Seguro por sí solos, error de parseo cuando los sigue un espacio | Seguro | Sí | También valen |
: | Seguro por sí solo, error de parseo cuando lo sigue un espacio | Error de parseo cuando lo sigue un espacio, esté donde esté | Sí | También valen |
" | Error de parseo | Seguro | Sí | Solo con escapes \" |
' | Error de parseo | Seguro | No: dóblala como '' | Usa estas |
De aquí salen dos cosas. Primero, en medio del valor solo son peligrosos : y #, así que url: http://example.com/a,b no necesita comillas: todo lo demás es un problema de principio de valor. Segundo, las comillas simples cubren todos los casos salvo una comilla simple literal, y por eso son la opción más segura cuando pegas rutas de Windows o expresiones regulares. Recurre a las comillas dobles cuando necesites que \n o \t signifiquen un salto de línea o un tabulador de verdad.
La sintaxis de plantillas {{ }} al inicio de un valor rompe el YAML
Si pasas una plantilla de Helm o un archivo de Ansible sin renderizar directamente a un parser de YAML, la llave inicial { activa la trampa de los caracteres especiales:
# Plantilla de Helm, antes de renderizar
image: {{ .Values.image }}
El {{ se parsea como dos mapeos de flujo anidados, y el modo de fallo depende del parser. En nuestras pruebas (2026-07-12, script de reproducción en el repositorio bajo scripts/benchmarks/yaml-syntax-errors/), PyYAML y ruamel.yaml se detienen con un error found unhashable key, pero js-yaml y eemeli/yaml no lanzan ningún error y devuelven en silencio un objeto deformado como {"image": {"[object Object]": null}}. La versión silenciosa es la peligrosa, porque nada falla hasta mucho después en tu pipeline.
Hay dos soluciones: entrecomillar el valor completo para que sea una cadena (image: "{{ .Values.image }}"), o validar el YAML solo después de renderizar la plantilla. Ten en cuenta que el ${{ }} de GitHub Actions empieza por $, así que nunca se parsea como un mapeo de flujo y no tiene este problema.
Cadenas multilínea
YAML tiene dos operadores para bloques de texto largos.
El bloque literal (|) conserva los saltos de línea exactamente como están escritos:
description: |
This is line one.
This is line two.
This is line four, after a blank line.
El escalar plegado (>) reemplaza los saltos de línea simples por espacios, lo que resulta útil para ajustar párrafos largos en el archivo fuente:
paragraph: >
This long sentence is split across
multiple lines in the source, but YAML
will fold it into a single line.
Indicadores de recorte: eliminar, recortar y conservar los saltos de línea finales
Los escalares de bloque de YAML aceptan un indicador de recorte (chomping) que decide qué ocurre con los saltos de línea finales después del valor. El indicador va inmediatamente después de | o >.
| Indicador | Comportamiento | Ejemplo |
|---|---|---|
| (ninguno) — clip | Conserva un único salto de línea final. Predeterminado. | | |
- — strip | Elimina todos los saltos de línea finales. | |- >- |
+ — keep | Conserva todas las líneas en blanco finales. | |+ >+ |
clip: |
line one
line two
strip: |-
line one
line two
keep: |+
line one
line two
Los mismos tres modos se aplican a la forma plegada (>, >-, >+). Usa |- cuando incrustes YAML dentro de un JSON o de una variable de entorno que no debe tener un salto de línea final. Usa |+ cuando generes scripts en los que las líneas en blanco finales importan.
Tipos e inferencia del parser
YAML infiere los tipos a partir de los valores sin comillas. El mismo literal puede convertirse en un entero, un número de coma flotante, una fecha o una cadena según la versión de YAML que implemente tu parser y el esquema que utilice.
integer: 42
hex: 0xFF # 255 (integer, hexadecimal)
octal: 0o17 # 15 (integer, octal, YAML 1.2)
octal_legacy: 0644 # 420 (integer, octal, YAML 1.1) — trampa del modo de archivo
float: 3.14
negative: -7
exponential: 1e3 # 1000.0 (float, notación científica)
infinity: .inf # +Infinity (float)
negative_infinity: -.inf
not_a_number: .nan # NaN (float)
boolean_true: true
boolean_false: false
null_value: null
tilde_null: ~
date: 2026-04-13
timestamp: 2026-04-13T09:30:00Z
Cualquiera de estos puede forzarse a cadena entrecomillándolo:
version_string: "1.0" # no es el número 1.0
zip_code: "07030" # no es el número 7030
file_mode: "0644" # string, no un entero octal
La siguiente tabla resume en qué se convierten los literales sin comillas en un cargador moderno con esquema Core de YAML 1.2 (PyYAML, js-yaml, el predeterminado de SnakeYAML), frente a un cargador de YAML 1.1 (PyYAML antiguo, Symfony YAML). La mayoría de las sorpresas viven en la diferencia entre estas columnas.
| Literal | YAML 1.2 Core | YAML 1.1 | A qué prestar atención |
|---|---|---|---|
42 | integer (42) | integer (42) | — |
0xFF | integer (255) | integer (255) | el parseo hexadecimal es intencional |
0o17 | integer (15) | (no reconocido) | solo en YAML 1.2 |
0644 | integer (644) | integer (420, octal) | los modos de archivo cambian entre versiones |
1e3 | float (1000.0) | float (1000.0) | algunas herramientas omiten .0 al mostrarlo |
.inf / -.inf | float (±Infinity) | float (±Infinity) | no serializable en JSON |
.nan | float (NaN) | float (NaN) | no serializable en JSON |
2026-04-13 | string | date (objeto de fecha) | el ida y vuelta JSON ↔ YAML cambia el tipo |
2026-04-13T09:30Z | string | timestamp | el mismo problema |
true / false | boolean | boolean | — |
yes / no / on / off | string | boolean | el "problema de Noruega" |
NO | string | boolean (false) | se trata a continuación |
~ / null / Null / NULL | null | null | se parsean todas las grafías |
1.0 | float (1.0) | float (1.0) | algunas herramientas lo reserializan como 1 |
Si tu parser está cerca de producción de algún modo, trata todo lo que aparezca en la columna de la derecha como un posible bug. La forma más rápida de averiguar qué versión usa tu cargador es pegar un archivo representativo en el conversor YAML a JSON de FormatArc e inspeccionar la salida JSON: "NO" frente a false, "2026-04-13" frente a una cadena de fecha ISO, y así sucesivamente.
La razón por la que existe esta diferencia entre columnas es que YAML 1.1 y YAML 1.2 definen la inferencia de tipos de forma distinta. YAML 1.1 arrastraba un amplio conjunto de etiquetas de tipo implícitas, incluidos los timestamps, los números sexagesimales (base 60) y el extenso vocabulario booleano que provoca el problema de Noruega. YAML 1.2 lo reemplazó por el esquema CoreSe abre en una pestaña nueva, más acotado, que limita los booleanos a true y false (la expresión regular del Core de la especificación también acepta las formas con mayúscula inicial y todo en mayúsculas True/TRUE/False/FALSE, pero ya no yes/no/on/off), elimina las etiquetas implícitas de timestamp y sexagesimal, y por lo demás refleja los tipos de valor de JSON. El conjunto completo de expresiones regulares que decide si un literal es un entero, un float, un booleano o un nulo está publicado en la especificación de YAML 1.2.2Se abre en una pestaña nueva. Cuando dos herramientas no se ponen de acuerdo sobre lo que significa un valor sin comillas, la diferencia casi siempre se remonta a que una implementa las reglas de tipos de la 1.1 y la otra implementa el esquema Core de la 1.2.
El problema de Noruega: cuando NO se convierte en false
El "problema de Noruega" es la trampa de YAML más citada. Los parsers de YAML 1.1 (que siguen siendo el predeterminado en muchas herramientas, incluidas PyYAML, Symfony YAML y las versiones antiguas de SnakeYAML) interpretan un NO simple como el booleano false. Así que una lista de códigos de país escrita de esta manera:
countries:
- DE
- FR
- NO
- SE
se convierte silenciosamente en ["DE", "FR", false, "SE"] al parsearse. La misma trampa salta con YES, ON, OFF, Y, N e incluso con variantes en mayúsculas según el parser.
La solución es entrecomillar cualquier valor que pueda interpretarse mal:
countries:
- "DE"
- "FR"
- "NO"
- "SE"
YAML 1.2 redujo los booleanos solo a true y false, pero la mayoría de las herramientas de producción todavía incluyen un cargador de la era 1.1. Cuando escribas códigos de país, códigos de idioma de dos letras, cadenas de versión o cualquier identificador corto, entrecomíllalo. Si mantienes una configuración independiente del parser, pégala en el conversor YAML a JSON de FormatArc: la salida JSON muestra al instante si tu NO sobrevivió como cadena.
Las reglas exactas viven en las especificaciones oficiales: la especificación de YAML 1.2.2Se abre en una pestaña nueva define el conjunto estricto de booleanos actual, mientras que la especificación de YAML 1.1Se abre en una pestaña nueva es la que todavía implementan la mayoría de las herramientas heredadas. Saber qué versión sigue tu cargador te dice si NO se parsea como cadena o como false.
Comentarios
Los comentarios comienzan con # y se extienden hasta el final de la línea. Pueden ocupar una línea propia o ir después de un valor.
# Número máximo de reintentos para las peticiones al upstream
retries: 3 # Más que esto y superamos el tiempo de espera del upstream
Los comentarios son una de las mayores ventajas de YAML sobre JSON para archivos de configuración: úsalos para explicar por qué existe un ajuste, no qué es. Al convertir a JSON se eliminan todos los comentarios, así que mantén el archivo YAML como tu fuente de la verdad. Si tienes que apañártelas con JSON, consulta cómo añadir comentarios a JSON para conocer las soluciones con JSONC y JSON5.
Anclas y alias para reutilizar
YAML te permite definir un valor una vez con &anchor y referenciarlo en otro lugar con *alias. La clave de fusión <<: incorpora un mapeo como un conjunto de valores predeterminados.
defaults: &defaults
adapter: postgres
host: db.internal
pool: 5
development:
<<: *defaults
database: myapp_dev
production:
<<: *defaults
database: myapp_prod
pool: 20
production parte de defaults y luego sobrescribe pool. Es una forma limpia de compartir configuración entre entornos sin copiar y pegar.
Claves de fusión (<<:) para compartir configuración
La clave de fusión <<: es el complemento más útil de las anclas. Incorpora las claves de un mapeo en otro, de modo que puedes expresar "igual que aquel, pero con estos cambios" sin repetirte. Docker Compose, GitLab CI y el database.yml de Rails dependen de este patrón.
base: &base
image: node:20
restart: unless-stopped
environment:
NODE_ENV: production
services:
api:
<<: *base
command: npm run start:api
worker:
<<: *base
command: npm run start:worker
environment:
NODE_ENV: production
WORKER_QUEUE: high
Dos cosas que recordar:
- La clave de fusión solo fusiona en un nivel. Los mapeos anidados (como
environmentarriba) se reemplazan por completo, no se fusionan en profundidad. - La clave de fusión es una característica de YAML 1.1. Los parsers estrictos de YAML 1.2 pueden ignorarla; herramientas como Docker Compose y GitLab la siguen admitiendo porque se anclan a la semántica de 1.1.
Esquemas y etiquetas: cómo decide YAML los tipos
YAML 1.2 define tres esquemas que controlan cómo se interpretan los literales sin comillas:
- FailSafe: solo cadenas, mapeos y secuencias. El esquema más seguro; todo lo demás es una cadena. Rara vez es el predeterminado.
- JSON: tipos compatibles con JSON: cadena, entero, coma flotante, booleano, nulo, mapeo y secuencia. Coincide con lo que produciría
JSON.parse. - Core: el predeterminado habitual. Añade las reglas de inferencia de tipos de la tabla anterior (hex, octal,
.inf,.nan,~).
La mayoría de los parsers incluyen Core (safe_load de PyYAML, el predeterminado de js-yaml, SafeConstructor de SnakeYAML). Symfony YAML sigue usando por defecto la semántica de YAML 1.1. Saber qué esquema usa tu cargador te dice qué fila de la tabla de tipos aplica.
Cuando el esquema se equivoca (por ejemplo, version: 1.0 se parsea como coma flotante cuando querías una cadena), usa una etiqueta explícita para anularlo:
version: !!str 1.0 # fuerza la cadena "1.0"
count: !!int "42" # fuerza el entero 42 aunque esté entre comillas
empty: !!null "" # null explícito en lugar de cadena vacía
El prefijo !! significa "usa la etiqueta de la biblioteca de etiquetas predeterminada". Las etiquetas personalizadas usan un solo ! (por ejemplo, !Ref en las plantillas de CloudFormation) y requieren que el parser las entienda. La mayoría de los archivos YAML a nivel de aplicación solo necesitan !!str para desactivar las trampas de tipos.
Archivos con múltiples documentos
Un único archivo YAML puede contener varios documentos separados por ---.
---
kind: Service
name: web
---
kind: Deployment
name: web
replicas: 3
Este es el mismo formato que usa Kubernetes cuando concatenas varios manifiestos. JSON no tiene equivalente: convertir un YAML de múltiples documentos a JSON te obliga a elegir un solo documento o a envolverlos en un array externo.
Dónde funcionan realmente las anclas, las claves de fusión y los múltiples documentos (matriz de compatibilidad)
Las anclas, las claves de fusión y los flujos de múltiples documentos son todos YAML válido, pero que funcionen depende por completo de dónde los pegues. Medimos directamente los cuatro parsers y Docker Compose (2026-07-12, scripts de reproducción en el repositorio bajo scripts/benchmarks/yaml-tool-acceptance/) y consultamos las fuentes oficiales de las plataformas alojadas.
| Entorno | Anclas & * | Claves de fusión <<: | Múltiples documentos --- |
|---|---|---|---|
| js-yaml | Compatible (medido) | Compatible (medido) | load da error; usa loadAll (medido) |
| PyYAML | Compatible (medido) | Compatible (medido) | safe_load da error; usa safe_load_all (medido) |
| yaml (eemeli), el parser detrás del conversor de FormatArc | Compatible (medido) | No se expande por defecto: << queda como clave literal (medido) | parse da error; usa parseAllDocuments (medido) |
| Docker Compose v5.3.0 | Compatible (medido) | Compatible (medido) | Aceptado: los documentos se fusionan en una sola configuración (medido) |
| GitHub Actions | Compatible desde el 2025-09-18Se abre en una pestaña nueva | No compatible: falla con un error de sintaxisSe abre en una pestaña nueva | No se menciona en la documentación oficial |
| GitLab CI | CompatibleSe abre en una pestaña nueva | CompatibleSe abre en una pestaña nueva | No se menciona en la documentación oficial |
| Kubernetes (kubectl) | No explícito en la documentación oficial | No explícito en la documentación oficial | CompatibleSe abre en una pestaña nueva |
Tres cosas que conviene notar:
- GitHub Actions separa el par: las anclas llegaron en septiembre de 2025, pero
<<:sigue fallando con un error de sintaxis, así que un workflow copiado desde GitLab CI no se traslada limpiamente. - eemeli/yaml usa YAML 1.2 por defecto, versión que eliminó las claves de fusión de la especificación, así que
<<:no se expande y acabas en silencio con una clave literal"<<"en lugar de los valores fusionados. - La compatibilidad con múltiples documentos es una cuestión de API: los cuatro parsers rechazan los flujos
---a través de su API de documento único y los aceptan a través de la de múltiples documentos.
Ejemplos de YAML del mundo real
Las mismas reglas de sintaxis aplican tanto si escribes una configuración de cinco líneas como un manifiesto de producción. Aquí están los tres lugares más comunes donde te encontrarás con YAML en 2026.
Manifiesto de Deployment de Kubernetes
Un Deployment mínimo ejercita mapeos, secuencias, cadenas multilínea y los booleanos del problema de Noruega, todo a la vez. La mayoría de los fallos aquí provienen de desviaciones de indentación en el bloque spec.template.spec.containers.
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
labels:
app: web
tier: frontend
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx:1.27-alpine
ports:
- containerPort: 80
env:
- name: FEATURE_FLAG_NEW_HEADER
value: "true" # entrecomillado a propósito: true sin comillas es un booleano
resources:
limits:
cpu: "500m"
memory: 256Mi
Fíjate en que value: "true" está entrecomillado. Sin las comillas, Kubernetes aceptaría tranquilamente el booleano y tu contenedor recibiría True (al estilo de Python) o no arrancaría, según el lenguaje. El desglose error por error está en la siguiente sección.
Flujo de trabajo de GitHub Actions
Los flujos de trabajo de GitHub Actions son mapeos profundamente anidados con frecuentes scripts multilínea. El bloque run es donde los modificadores | (literal) y > (plegado) de YAML demuestran su valor.
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20" # entrecomillado para conservar el cero final
- name: Install
run: npm ci
- name: Test
run: |
npm run lint
npm run build
npm test -- --run
El fallo más común aquí es quitar las comillas de node-version: "20": YAML lo convierte en el entero 20, que setup-node puede aceptar o no según la versión. Entrecomilla cualquier valor que "parezca" un número pero que deba seguir siendo una cadena.
Servicio de Docker Compose
Los archivos de Compose mezclan mapeos, secuencias, diccionarios de entorno y cadenas de montaje (bind-mount). Son lo bastante cortos como para pegarse completos y son una excelente forma de practicar la detección de problemas de indentación.
services:
web:
image: nginx:1.27-alpine
ports:
- "8080:80" # entrecomillado para evitar la lectura sexagesimal
environment:
NGINX_HOST: example.com
NGINX_PORT: "80" # entrecomillado: los valores de entorno deben ser cadenas
volumes:
- ./html:/usr/share/nginx/html:ro
depends_on:
- api
api:
build: ./api
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
interval: 30s
timeout: 5s
retries: 3
Dos trampas sutiles aquí: "8080:80" debe entrecomillarse (de lo contrario, los parsers de YAML 1.1 pueden leerlo como un número sexagesimal), y todos los valores bajo environment: deberían entrecomillarse porque Docker Compose finalmente necesita cadenas. Los errores que vienen a continuación muestran qué aspecto tienen cuando salen mal.
Errores comunes, y qué dice exactamente cada parser sobre ellos (medido)
Estos son los errores de YAML que en algún momento atrapan a casi todo el mundo.
- Tabuladores en lugar de espacios: un carácter de tabulación oculto rompe el parseo con un error confuso
- Falta de espacio después de los dos puntos:
key:valuees una sola cadena, no un mapeo - Indentación inconsistente: los elementos del mismo nivel deben compartir la misma indentación
- Booleanos a partir de
NO,OFF,YES,ONsin comillas: el "problema de Noruega" - Dos puntos en valores sin comillas:
time: 10:30podría parsearse como un número sexagesimal - Mezclar la sintaxis de bloque y de flujo de formas que el parser no espera
- Claves duplicadas en el mismo mapeo: el comportamiento depende de la implementación
Lo molesto cuando buscas estos errores es que el mismo fallo produce un mensaje completamente distinto en cada parser. Pasamos seis errores representativos a js-yaml, a yaml (eemeli) —el parser detrás del conversor de FormatArc— y a PyYAML, y registramos las cadenas exactas que emiten (medido el 2026-07-12; los registros en bruto de los cuatro parsers, incluido ruamel.yaml, junto con el script de reproducción, están en el repositorio bajo scripts/benchmarks/yaml-syntax-errors/). El script de reproducción cubre también un séptimo caso, la trampa de las plantillas {{ }}, pero ese tiene su propia sección más arriba, así que no se repite en esta tabla.
| Error | Mensaje de js-yaml | Mensaje de yaml (eemeli) | Mensaje de PyYAML |
|---|---|---|---|
| Tabulador usado para indentar | tab characters must not be used in indentation (línea 2) | Tabs are not allowed as indentation (línea 2) | found character '\t' that cannot start any token (línea 2) |
| Indentación inconsistente (2 vs 3 espacios) | bad indentation of a mapping entry (línea 3) | Nested mappings are not allowed in compact mappings (línea 2) | mapping values are not allowed here (línea 3) |
: sin comillas dentro de un valor (url: http://x.com: 8080) | bad indentation of a mapping entry (línea 1, col 24) | Nested mappings are not allowed in compact mappings (línea 1, col. 6) | mapping values are not allowed here (línea 1, col 24) |
| Comilla doble sin cerrar | unexpected end of the stream within a double quoted scalar (última línea) | Missing closing "quote (línea 2, col. 8) | while scanning a quoted scalar ... found unexpected end of stream (apunta a la comilla de apertura) |
*alias a un ancla no definida | unidentified alias "missing" | Unresolved alias (the anchor must be set before the alias): missing (no informa la línea) | found undefined alias 'missing' |
Flujo [ sin cerrar | missed comma between flow collection entries (línea siguiente) | Flow sequence in block collection must be sufficiently indented and end with a ] (línea 2) | while parsing a flow sequence ... expected ',' or ']' |
Tres consejos para leerlos. Primero, mapping values are not allowed here (PyYAML) y bad indentation of a mapping entry (js-yaml) parecen no tener relación, pero son errores hermanos: ambos significan "hay un : donde no puede empezar un mapeo", y el Nested mappings are not allowed in compact mappings de eemeli es el mismo diagnóstico con una tercera redacción. Segundo, el número de línea reportado cambia entre parsers: ante una comilla sin cerrar, js-yaml apunta al final del flujo mientras que PyYAML apunta a la comilla de apertura, así que revisa tanto la línea reportada como el punto donde abre la comilla más cercana. Tercero, ante el mismo documento eemeli suele apuntar una línea antes que js-yaml, porque informa dónde empezó el mapeo compacto y no dónde se rompió.
La forma más rápida de detectarlos es dejar que un parser lea el archivo. Puedes hacerlo sin instalar nada pegando tu YAML en el conversor YAML a JSON de FormatArc. Si el archivo es válido, verás el equivalente en JSON al instante. Si no lo es, el conversor te dice que el documento tiene un error de sintaxis y te da la línea a la que saltar: a propósito no imprime el mensaje en bruto del parser, así que, cuando quieras buscar la redacción exacta que emite tu propia cadena de herramientas, usa la tabla anterior.
Solución: "It is forbidden to specify block composed value at the same line as key"
Se trata de una inspección de YAML de la familia de IDEs JetBrains/IntelliJ (IntelliJ IDEA, PyCharm, GoLand, Rider, DataGrip). El texto exacto está definido en YAMLBundle.propertiesSe abre en una pestaña nueva como annotator.same.line.composed.value.message.
El mensaje significa una sola cosa: una colección de bloque empieza en la misma línea que su clave. Al leer el código del annotatorSe abre en una pestaña nueva se ve que solo comprueba dos formas: una secuencia de bloque cuyo primer elemento comparte línea con la clave, y un mapeo de bloque cuyo primer par clave-valor comparte línea con la clave. Nada más la dispara.
Forma 1: una secuencia de bloque que empieza en la línea de la clave.
# Dispara la inspección
key: - item1
- item2
Solución: baja el primer elemento a su propia línea.
key:
- item1
- item2
Forma 2: un mapeo de bloque que empieza en la línea de la clave.
# Dispara la inspección
key: sub: value
sub2: value2
Solución: el mismo tratamiento, cortar después de los dos puntos.
key:
sub: value
sub2: value2
Ninguna de las dos formas es una manía del IDE: son errores de YAML. Los parsers también las rechazan, con un texto cercano al de IntelliJ. El paquete yaml devuelve Unexpected block-seq-ind on same line with key para la forma 1 y Nested mappings are not allowed in compact mappings para la forma 2.
No es la inspección de claves duplicadas. Las claves de mapeo duplicadas producen otro mensaje, Key 'x' is duplicated (YAMLDuplicatedKeysInspection.duplicated.key en el mismo bundle). Si tu IDE dice que una clave está duplicada, la solución es renombrarla o cambiarla de padre, y no tiene relación con dónde empieza la colección de bloque.
Cuando el mensaje aparece en plantillas Helm o Jinja válidas. El annotator interrumpe la comprobación cuando el elemento contiene fragmentos de plantilla inyectados, así que una plantilla bien escrita no debería marcarse. Si aun así aparece, es un falso positivo conocido — JetBrains lo registra en incidencias como IJPL-64437Se abre en una pestaña nueva — y el archivo no necesita ningún cambio.
Después de editar, pega el archivo en YAML a JSON para confirmar que la colección de bloque ya empieza en su propia línea. La conversión se ejecuta por completo en tu navegador: tu YAML no se sube a ningún sitio.
Valida tu YAML en el navegador con FormatArc
Las herramientas exclusivamente de navegador de FormatArc funcionan muy bien como un linter rápido de YAML:


- YAML a JSON: pega YAML, ve la salida JSON y obtén errores con número de línea cuando algo está mal
- JSON a YAML: ¿partes de JSON y quieres ver el equivalente en YAML? Úsalo para aprender la correspondencia entre ambos formatos
- Formateador de JSON: formatea con sangría el JSON que sale de tu YAML
Todo se ejecuta en el navegador. Nada sale de tu máquina, así que puedes pegar con seguridad archivos de configuración internos o secretos mientras depuras.
Preguntas frecuentes
¿Puedo usar tabuladores para la indentación en YAML?
No. La especificación de YAML exige espacios, y un carácter de tabulación literal producirá un error de sintaxis en la mayoría de los parsers. Configura tu editor para que inserte dos espacios al pulsar Tab en un archivo .yml o .yaml.
¿Cuál es la diferencia entre .yml y .yaml?
Ninguna. Todos los parsers de YAML tratan ambas extensiones de forma idéntica. La especificación oficial recomienda .yaml, pero .yml es común y está totalmente admitida.
¿Siempre necesito comillas alrededor de las cadenas?
No. YAML te permite escribir la mayoría de las cadenas sin comillas. Añade comillas solo cuando el valor se interpretaría de otro modo como un tipo diferente, o cuando comienza con un carácter especial como -, :, [, {, | o >.
¿Por qué version: 1.0 se convierte en 1?
YAML parsea 1.0 como un número de coma flotante, y algunas herramientas luego serializan el flotante como 1. Para mantenerlo como cadena, entrecomíllalo: version: "1.0".
¿Cuántos espacios debo usar para la indentación?
Dos es la convención que usan Kubernetes, Docker Compose, GitHub Actions y la mayoría de los ejemplos que verás en línea. Cuatro está bien siempre que seas coherente dentro de un mismo archivo.
¿Cómo valido un archivo YAML sin instalar nada?
Pégalo en el conversor YAML a JSON de FormatArc. Si el YAML es válido, verás la salida JSON al instante. Si no lo es, el mensaje de error incluye el número de línea para que puedas corregir el problema rápido.
¿Puedo escribir varios documentos YAML en un solo archivo?
Sí. Sepáralos con una línea que contenga únicamente ---. Así es como suelen empaquetarse los manifiestos de Kubernetes. Un único archivo YAML puede contener tantos documentos como quieras.
Lecturas relacionadas
- ¿Qué es YAML?: la introducción de alto nivel si eres nuevo en el formato
- YAML vs JSON: diferencias clave: compara YAML y JSON lado a lado
- Cómo convertir YAML a JSON: guía de conversión paso a paso
- Guía de sintaxis de JSON: el equivalente de este artículo para JSON
- Cómo añadir comentarios a JSON: la solución alternativa cuando no puedes usar YAML
- Frontmatter YAML a JSON en Markdown: matriz SSG (Hugo / Jekyll / Astro) y tipos YAML que se rompen al convertir
Resumen
- YAML usa la indentación, no llaves, para expresar la estructura
- Solo espacios: nunca tabuladores, y sé coherente
- Entrecomilla las cadenas solo cuando se malinterpretarían
- Usa comentarios, cadenas multilínea y anclas para hacer legibles los archivos de configuración
- Valida tu YAML rápido pegándolo en la herramienta YAML a JSON de FormatArc