TL;DR — sintaxe YAML em um minuto
- Use apenas espaços (sem tabs). A indentação de 2 espaços é a convenção de fato.
key: valueprecisa de um espaço após os dois-pontos.key:valueé uma única string.- Listas usam
-(traço + espaço). Mapeamentos usamkey: value. - Coloque entre aspas valores que poderiam ser mal interpretados como números, booleanos ou datas:
version: "1.0". - Encontre erros rapidamente colando no validador de YAML para JSON do FormatArc — as mensagens com número de linha apontam direto para o problema.
O que é YAML e onde você vai encontrá-lo
YAML (YAML Ain't Markup Language) é um formato de texto legível para humanos voltado a dados estruturados. Ele cobre o mesmo modelo de dados do JSON — strings, números, booleanos, nulos, listas e mapeamentos — mas a sintaxe é baseada em indentação, e não em chaves e colchetes.
Se você trabalha com ferramentas modernas de DevOps ou cloud-native, já se deparou com YAML:
- Manifestos do Kubernetes e Helm charts
- Arquivos do Docker Compose
- Workflows de GitHub Actions, GitLab CI e CircleCI
- Playbooks do Ansible
- Especificações OpenAPI
- Geradores de sites estáticos (Hugo, Jekyll, Eleventy)
Este guia percorre cada parte da sintaxe YAML que você de fato vai usar, com exemplos e uma lista dos erros que mais pegam os iniciantes. Se quiser comparar YAML e JSON diretamente, veja YAML vs JSON: principais diferenças, ou leia o passo a passo Como converter YAML para JSON.
Os três blocos de construção
Tudo em um arquivo YAML é uma de três coisas:
- Escalar — um único valor, como uma string, número, booleano ou nulo
- Sequência — uma lista ordenada de itens
- Mapeamento — um conjunto não ordenado de pares chave-valor
Você pode aninhar esses elementos livremente. Um mapeamento pode conter listas, uma lista pode conter mapeamentos, e ambos podem conter outros mapeamentos ou listas. Isso é tudo de que você precisa para representar qualquer estrutura compatível com JSON.
Regras de indentação
A indentação é como o YAML expressa o aninhamento. Algumas regras para internalizar:
- Use espaços, nunca tabs — um caractere de tab literal é um erro de sintaxe na maioria dos parsers
- Escolha um tamanho de indentação (2 espaços é a convenção) e mantenha a consistência
- Todos os itens no mesmo nível devem ter a mesma indentação
- A indentação determina a estrutura; não existe delimitador de fechamento
Aqui está um exemplo simples e válido:
database:
host: localhost
port: 5432
credentials:
user: admin
password: secret
database contém um mapeamento, que contém host, port e credentials. credentials é um mapeamento aninhado. A indentação de dois espaços diz ao YAML exatamente como a estrutura se encaixa.
Escrevendo pares chave-valor (mapeamentos)
Um mapeamento é escrito como key: value, com um espaço após os dois-pontos. O espaço é obrigatório — key:value é uma única string, não um mapeamento.
name: Alice
age: 30
is_admin: true
bio: null
As chaves normalmente são strings simples. Elas podem conter espaços se estiverem entre aspas:
"full name": Alice Cooper
Os valores podem ser de qualquer tipo YAML: escalar, sequência ou outro mapeamento.
Escrevendo listas (sequências)
Uma sequência é uma série de linhas que começam com - (um traço seguido de um espaço).
fruits:
- apple
- banana
- cherry
As listas podem conter qualquer tipo de valor, incluindo mapeamentos aninhados:
users:
- name: Alice
role: admin
- name: Bob
role: editor
Cada traço inicia um novo item da lista. Os campos que se seguem pertencem a esse item até que outro traço apareça no mesmo nível de indentação.
Também existe uma forma inline (flow), que se parece com JSON:
fruits: [apple, banana, cherry]
users: [{name: Alice, role: admin}, {name: Bob, role: editor}]
A forma flow é prática para listas pequenas, mas fica mais difícil de ler quando os dados crescem. Use a forma em bloco para qualquer coisa não trivial.
Strings: quando usar aspas
A maioria das strings em YAML pode ser escrita sem aspas.
greeting: Hello, world
Você só precisa de aspas quando:
- O valor seria, de outra forma, interpretado como um tipo diferente:
version: "1.0",country: "NO",postal_code: "07030" - O valor começa com um caractere especial, como
-,:,[,{,|,>,*,&,!,%,@ - O valor contém dois-pontos seguidos de um espaço (que, de outra forma, pareceria um mapeamento)
- Você quer incluir sequências de escape, como
\nou\t
O YAML aceita aspas simples e duplas. As aspas duplas interpretam as sequências de escape; as aspas simples tratam tudo literalmente.
escaped: "line1\nline2"
literal: 'line1\nline2'
Strings de várias linhas
O YAML tem dois operadores para blocos de texto longos.
O bloco literal (|) preserva as quebras de linha exatamente como foram escritas:
description: |
This is line one.
This is line two.
This is line four, after a blank line.
O escalar dobrado (>) substitui quebras de linha simples por espaços, o que é útil para quebrar parágrafos longos no arquivo de origem:
paragraph: >
This long sentence is split across
multiple lines in the source, but YAML
will fold it into a single line.
Indicadores de chomp: strip, clip e manter quebras de linha finais
Os escalares em bloco do YAML aceitam um indicador de chomping que decide o que acontece com as quebras de linha finais após o valor. O indicador vem imediatamente após | ou >.
| Indicador | Comportamento | Exemplo |
|---|---|---|
| (nenhum) — clip | Mantém uma única quebra de linha final. Padrão. | | |
- — strip |
Remove todas as quebras de linha finais. | |- >- |
+ — keep |
Mantém todas as linhas em branco finais. | |+ >+ |
clip: |
line one
line two
strip: |-
line one
line two
keep: |+
line one
line two
Os mesmos três modos se aplicam à forma dobrada (>, >-, >+). Use |- quando você embute YAML dentro de um JSON ou de uma variável de ambiente que não pode ter uma quebra de linha final. Use |+ quando você gera scripts em que as linhas em branco finais importam.
Tipos e inferência do parser
O YAML infere tipos a partir de valores sem aspas. O mesmo literal pode se tornar um inteiro, um float, uma data ou uma string, dependendo da versão do YAML que o seu parser implementa e de qual schema ele usa.
integer: 42
hex: 0xFF # 255 (integer, hex)
octal: 0o17 # 15 (integer, octal, YAML 1.2)
octal_legacy: 0644 # 420 (integer, octal, YAML 1.1) — file mode trap
float: 3.14
negative: -7
exponential: 1e3 # 1000.0 (float, scientific notation)
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
Qualquer um desses pode ser forçado a virar string usando aspas:
version_string: "1.0" # not the number 1.0
zip_code: "07030" # not the number 7030
file_mode: "0644" # string, not octal integer
A próxima tabela resume no que os literais sem aspas se transformam em um loader moderno do schema Core do YAML 1.2 (PyYAML, js-yaml, o padrão do SnakeYAML), em comparação com um loader YAML 1.1 (PyYAML legado, Symfony YAML). A maioria das surpresas vive nessa diferença entre colunas.
| Literal | YAML 1.2 Core | YAML 1.1 | Cuidado com |
|---|---|---|---|
42 |
integer (42) | integer (42) | — |
0xFF |
integer (255) | integer (255) | o parse de hex é intencional |
0o17 |
integer (15) | (não reconhecido) | só no YAML 1.2 |
0644 |
integer (644) | integer (420, octal) | modos de arquivo mudam entre versões |
1e3 |
float (1000.0) | float (1000.0) | a exibição perde o .0 em algumas ferramentas |
.inf / -.inf |
float (±Infinity) | float (±Infinity) | não serializável em JSON |
.nan |
float (NaN) | float (NaN) | não serializável em JSON |
2026-04-13 |
string | date (objeto de data) | converter JSON ↔ YAML de ida e volta muda o tipo |
2026-04-13T09:30Z |
string | timestamp | mesmo problema |
true / false |
boolean | boolean | — |
yes / no / on / off |
string | boolean | o "problema da Noruega" |
NO |
string | boolean (false) | abordado a seguir |
~ / null / Null / NULL |
null | null | toda capitalização vira null |
1.0 |
float (1.0) | float (1.0) | re-serializado como 1 por algumas ferramentas |
Se o seu parser está perto de produção, trate qualquer coisa na coluna mais à direita como um bug em potencial. A forma mais rápida de descobrir qual versão o seu loader usa é colar um arquivo representativo no conversor de YAML para JSON do FormatArc e inspecionar a saída JSON: "NO" versus false, "2026-04-13" versus uma string de data ISO, e assim por diante.
A razão de essa diferença entre colunas existir é que o YAML 1.1 e o YAML 1.2 definem a inferência de tipos de formas diferentes. O YAML 1.1 carregava um amplo conjunto de tags de tipo implícitas — incluindo timestamps, números sexagesimais (base 60) e o vasto vocabulário booleano que causa o problema da Noruega. O YAML 1.2 substituiu isso pelo schema Core, mais restrito, que limita os booleanos a true e false (a regex do Core da especificação também aceita as formas com inicial maiúscula e tudo em maiúsculas True/TRUE/False/FALSE, mas não mais yes/no/on/off), descarta as tags implícitas de timestamp e sexagesimal e, no restante, espelha os tipos de valor do JSON. O conjunto completo de expressões regulares que decide se um literal é um inteiro, um float, um booleano ou um nulo está publicado na especificação do YAML 1.2.2. Quando duas ferramentas discordam sobre o que um valor sem aspas significa, a diferença quase sempre remonta a uma delas implementar as regras de tipo da 1.1 e a outra implementar o schema Core da 1.2.
O problema da Noruega: quando NO vira false
O "problema da Noruega" é a pegadinha de YAML mais citada. Os parsers do YAML 1.1 (ainda o padrão em muitas ferramentas — incluindo PyYAML, Symfony YAML e versões mais antigas do SnakeYAML) interpretam um NO sem aspas como o booleano false. Então uma lista de códigos de país escrita assim:
countries:
- DE
- FR
- NO
- SE
silenciosamente se torna ["DE", "FR", false, "SE"] depois de ser parseada. A mesma armadilha dispara para YES, ON, OFF, Y, N e até variantes em maiúsculas, dependendo do parser.
A correção é colocar entre aspas qualquer valor que possa ser mal interpretado:
countries:
- "DE"
- "FR"
- "NO"
- "SE"
O YAML 1.2 restringiu os booleanos a apenas true e false, mas a maioria das ferramentas de produção ainda traz um loader da era 1.1. Quando você escrever códigos de país, códigos de idioma de duas letras, strings de versão ou qualquer identificador curto, use aspas. Se você mantém uma config independente de parser, cole no conversor de YAML para JSON do FormatArc — a saída JSON mostra na hora se o seu NO sobreviveu como string.
As regras exatas estão nas especificações oficiais: a especificação do YAML 1.2.2 define o conjunto estrito de booleanos de hoje, enquanto a especificação do YAML 1.1 é a que a maioria das ferramentas legadas ainda implementa. Saber qual versão o seu loader segue diz se NO é parseado como string ou como false.
Comentários
Os comentários começam com # e vão até o fim da linha. Eles podem ocupar uma linha sozinhos ou vir depois de um valor.
# Maximum number of retries for upstream requests
retries: 3 # Any higher and we exceed the upstream timeout
Os comentários são uma das maiores vantagens do YAML sobre o JSON para arquivos de configuração — use-os para explicar por que uma configuração existe, não o que ela é. A conversão para JSON descarta todos os comentários, então mantenha o arquivo YAML como a sua fonte da verdade. Se você precisa conviver com JSON, veja Como adicionar comentários ao JSON para as soluções com JSONC e JSON5.
Âncoras e aliases para reutilização
O YAML permite que você defina um valor uma única vez com &anchor e o referencie em outro lugar com *alias. A chave de merge <<: traz um mapeamento como um conjunto de valores padrão.
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 e então sobrescreve pool. Essa é uma forma limpa de compartilhar configuração entre ambientes sem copiar e colar.
Chaves de merge (<<:) para compartilhar config
A chave de merge <<: é a companheira mais útil das âncoras. Ela traz as chaves de um mapeamento para dentro de outro, então você pode expressar "igual àquilo, mas com estas sobrescritas" sem se repetir. Docker Compose, GitLab CI e o database.yml do Rails dependem desse padrão.
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
Duas coisas para lembrar:
- A chave de merge só faz merge em um nível. Mapeamentos aninhados (como
environmentacima) são substituídos por completo, e não combinados em profundidade. - A chave de merge é um recurso do YAML 1.1. Parsers estritos do YAML 1.2 podem ignorá-la; ferramentas como Docker Compose e GitLab ainda a suportam porque fixam a semântica da 1.1.
Schemas e tags: como o YAML decide os tipos
O YAML 1.2 define três schemas que controlam como os literais sem aspas são interpretados:
- FailSafe — apenas strings, mapeamentos e sequências. O schema mais seguro; todo o resto é uma string. Raramente é o padrão.
- JSON — tipos compatíveis com JSON: string, integer, float, boolean, null, mapeamento, sequência. Equivale ao que
JSON.parseproduziria. - Core — o padrão típico. Adiciona as regras de inferência de tipo da tabela acima (hex, octal,
.inf,.nan,~).
A maioria dos parsers traz o Core (safe_load do PyYAML, o padrão do js-yaml, o SafeConstructor do SnakeYAML). O Symfony YAML ainda usa por padrão a semântica do YAML 1.1. Saber qual schema o seu loader usa diz qual linha da tabela de tipos se aplica.
Quando o schema erra — version: 1.0 sendo parseado como float quando você queria uma string — use uma tag explícita para sobrescrever:
version: !!str 1.0 # forces string "1.0"
count: !!int "42" # forces integer 42 even though it is quoted
empty: !!null "" # explicit null instead of empty string
O prefixo !! significa "use a tag da biblioteca de tags padrão". Tags personalizadas usam um único ! (por exemplo !Ref em templates do CloudFormation) e exigem que o parser as entenda. A maioria dos arquivos YAML em nível de aplicação só precisa de !!str para desarmar as armadilhas de tipo.
Arquivos com vários documentos
Um único arquivo YAML pode conter vários documentos separados por ---.
---
kind: Service
name: web
---
kind: Deployment
name: web
replicas: 3
Esse é o mesmo formato que o Kubernetes usa quando você concatena vários manifestos. O JSON não tem equivalente — converter um YAML com vários documentos para JSON obriga você a escolher um documento ou a envolvê-los em um array externo.
Exemplos reais de YAML
As mesmas regras de sintaxe se aplicam, quer você esteja escrevendo uma config de cinco linhas ou um manifesto de produção. Aqui estão os três lugares mais comuns onde você vai encontrar YAML em 2026.
Manifesto de Deployment do Kubernetes
Um Deployment mínimo exercita mapeamentos, sequências, strings de várias linhas e os booleanos do problema da Noruega, tudo ao mesmo tempo. A maioria das falhas aqui vem de desvios de indentação no bloco 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" # quoted on purpose — bare true is a boolean
resources:
limits:
cpu: "500m"
memory: 256Mi
Repare que value: "true" está entre aspas. Sem as aspas, o Kubernetes aceitaria de bom grado o booleano e o seu container receberia True (estilo Python) ou falharia ao iniciar, dependendo da linguagem. A análise erro por erro está na próxima seção.
Workflow do GitHub Actions
Os workflows do GitHub Actions são mapeamentos profundamente aninhados com scripts de várias linhas frequentes. O bloco run é onde os modificadores | (literal) e > (dobrado) do YAML provam o seu 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" # quoted to keep the trailing zero
- name: Install
run: npm ci
- name: Test
run: |
npm run lint
npm run build
npm test -- --run
A quebra mais comum aqui é remover as aspas em torno de node-version: "20" — o YAML o coage ao inteiro 20, que o setup-node pode ou não aceitar, dependendo da versão. Coloque entre aspas qualquer valor que "pareça" um número, mas que deva permanecer como string.
Serviço do Docker Compose
Os arquivos do Compose misturam mapeamentos, sequências, dicionários de ambiente e strings de bind-mount. Eles são curtos o suficiente para colar por inteiro e são uma ótima forma de praticar a identificação de problemas de indentação.
services:
web:
image: nginx:1.27-alpine
ports:
- "8080:80" # quoted to avoid sexagesimal parsing
environment:
NGINX_HOST: example.com
NGINX_PORT: "80" # quoted: env values must be strings
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
Duas armadilhas sutis aqui: "8080:80" precisa estar entre aspas (caso contrário, parsers do YAML 1.1 podem lê-lo como um número sexagesimal), e todo valor sob environment: deve estar entre aspas, porque o Docker Compose, no fim das contas, precisa de strings. Os erros a seguir mostram como isso fica quando dá errado.
Erros comuns e como detectá-los
Estes são os erros de YAML que pegam quase todo mundo em algum momento.
- Tabs em vez de espaços — um caractere de tab escondido quebra o parsing com um erro confuso
- Falta de espaço após os dois-pontos —
key:valueé uma única string, não um mapeamento - Indentação inconsistente — itens no mesmo nível devem compartilhar a mesma indentação
- Booleanos a partir de
NO,OFF,YES,ONsem aspas — o "problema da Noruega" - Dois-pontos em valores sem aspas —
time: 10:30pode ser parseado como um número sexagesimal - Misturar sintaxe de bloco e de flow de formas que o parser não espera
- Chaves duplicadas no mesmo mapeamento — o comportamento depende da implementação
A forma mais rápida de detectar esses erros é deixar um parser ler o arquivo. Você pode fazer isso sem instalar nada, colando o seu YAML no conversor de YAML para JSON do FormatArc. Se o arquivo for válido, você verá o equivalente em JSON imediatamente. Se não for, a mensagem de erro inclui o número da linha, para que você possa ir direto ao problema.
Valide o seu YAML no navegador com o FormatArc
As ferramentas que rodam só no navegador do FormatArc funcionam bem como um linter rápido de YAML:


- YAML para JSON — cole o YAML, veja a saída JSON e receba erros com número de linha quando algo estiver errado
- JSON para YAML — partindo de JSON e quer ver o equivalente em YAML? Use isto para aprender o mapeamento entre os dois formatos
- Formatador de JSON — formate o JSON que sai do seu YAML
Tudo roda no navegador. Nada sai da sua máquina, então você pode colar com segurança arquivos de config internos ou segredos enquanto faz o debug.
Perguntas frequentes
Posso usar tabs para indentação em YAML?
Não. A especificação do YAML exige espaços, e um caractere de tab literal vai produzir um erro de sintaxe na maioria dos parsers. Configure o seu editor para inserir dois espaços quando você pressionar Tab em um arquivo .yml ou .yaml.
Qual é a diferença entre .yml e .yaml?
Nenhuma. As duas extensões são tratadas de forma idêntica por todos os parsers de YAML. A especificação oficial recomenda .yaml, mas .yml é comum e totalmente suportado.
Sempre preciso de aspas em torno das strings?
Não. O YAML permite que você escreva a maioria das strings sem aspas. Adicione aspas apenas quando o valor seria, de outra forma, parseado como um tipo diferente, ou quando ele começa com um caractere especial, como -, :, [, {, | ou >.
Por que version: 1.0 vira 1?
O YAML parseia 1.0 como um número de ponto flutuante, e algumas ferramentas depois serializam o float como 1. Para mantê-lo como string, use aspas: version: "1.0".
Quantos espaços devo usar para a indentação?
Dois é a convenção usada por Kubernetes, Docker Compose, GitHub Actions e pela maioria dos exemplos que você verá online. Quatro também serve, contanto que você seja consistente dentro de um único arquivo.
Como valido um arquivo YAML sem instalar nada?
Cole-o no conversor de YAML para JSON do FormatArc. Se o YAML for válido, você verá a saída JSON imediatamente. Se não for, a mensagem de erro inclui o número da linha, para que você corrija o problema rapidamente.
Posso escrever vários documentos YAML em um arquivo?
Sim. Separe-os com uma linha contendo apenas ---. É assim que os manifestos do Kubernetes costumam ser agrupados. Um único arquivo YAML pode conter quantos documentos você quiser.
Leitura relacionada
- O que é YAML? — a introdução de alto nível, se você é novo no formato
- YAML vs JSON: principais diferenças — compare YAML e JSON lado a lado
- Como converter YAML para JSON — guia de conversão passo a passo
- Guia de sintaxe JSON — o equivalente em JSON deste artigo
- Como adicionar comentários ao JSON — a solução para quando você não pode usar YAML
Resumo
- O YAML usa indentação, e não chaves, para expressar a estrutura
- Apenas espaços — nunca tabs, e seja consistente
- Use aspas em strings apenas quando elas seriam mal interpretadas
- Use comentários, strings de várias linhas e âncoras para tornar os arquivos de config legíveis
- Valide o seu YAML rapidamente colando-o na ferramenta de YAML para JSON do FormatArc