Pular para o conteúdo
Abrir o Kubepier

Kubernetes · referência

Exit codes no Kubernetes: 0, 1, 126, 127, 128, 137, 143

Equipe IA4CODE
engenharia de plataforma e SRE
publicado em 25 set 2026 6 min de leitura códigos reproduzidos num cluster k3s 1.35 de teste em 25 set 2026

TL;DR

O exit code é o número com que o processo principal do container terminou, e o Reason ao lado diz quem o encerrou. Acima de 128, é sinal: 137 é SIGKILL e 143 é SIGTERM. Medimos dois casos que confundem. Primeiro: comando inexistente só dá 127 quando um shell o executa; chamado direto, o container nem inicia e registra 128 com Reason StartError. Segundo: 137 nem sempre é memória. Um processo que roda como PID 1 ignora o SIGTERM, espera os 30 s de grace period e morre por SIGKILL, com 137 e Reason Error. Quando é memória, o Reason diz OOMKilled.

A tabela

Exit codeReasonO que éO que olhar
0CompletedO processo terminou com sucesso.Em Deployment, container que termina é reiniciado: o CMD precisa ficar em primeiro plano. Tarefa que termina é Job.
1ErrorErro genérico da aplicação.O log do container anterior (logs --previous) costuma ter a exceção nas últimas linhas.
126ErrorO shell achou o arquivo, mas não pôde executá-lo (sem permissão de execução).Só aparece quando um shell executa o comando; chamado direto no command, vira 128 (StartError).
127ErrorO shell não achou o comando.Idem: 127 só vem de shell. Sem shell, o erro é 128 com "executable file not found".
128StartErrorO container nem começou: o runtime não conseguiu executar o command.Leia state.terminated.message: ela diz o motivo exato, como "executable file not found in $PATH".
137OOMKilled ou Error128 + 9: SIGKILL. Ou o kernel matou por memória (OOMKilled), ou o kubelet matou depois do grace period.O Reason separa os dois: OOMKilled é memória; Error com 137 costuma ser processo que ignorou o SIGTERM.
139Error128 + 11: SIGSEGV, falha de segmentação.Binário nativo, biblioteca incompatível ou imagem da arquitetura errada (amd64 x arm64).
143Error128 + 15: o processo morreu pelo SIGTERM.Término pedido (rollout, scale-down, liveness, drain) sem tratamento do sinal. Se o processo trata e sai limpo, o registro é 0.

Acima de 128, o código é 128 + o número do sinal (convenção POSIX; lista de sinais em man 7 signal): 9 é SIGKILL, 11 é SIGSEGV, 15 é SIGTERM.

Como ler o código

O código sozinho engana; ele precisa do Reason. Os dois ficam juntos no estado do container: State para o container atual e Last State para o anterior, que é o que interessa quando o pod está reiniciando.

Reproduzimos cada código com um pod de teste de um container só. Esta é a saída real:

saída real, mensagens cortadas
kubectl -n loja get pods -o 'custom-columns=NOME:.metadata.name,EXIT:.status.containerStatuses[0].state.terminated.exitCode,MOTIVO:.status.containerStatuses[0].state.terminated.reason'
NOME          EXIT   MOTIVO
exit-0        0      Completed
exit-1        1      Error
exit-126      128    StartError
exit-126-sh   126    Error
exit-127      128    StartError
exit-127-sh   127    Error

Os pods exit-126 e exit-127 executam o comando direto no command; os com -sh no nome executam o mesmo comando por sh -c.

127 que vira 128

O 127 ("command not found") e o 126 ("permission denied") são códigos do shell. Quando o command do container aponta direto para um binário que não existe, não há shell para devolver 127: o runtime tenta executar, falha, e o container termina antes de começar, com exit 128 e Reason StartError. O motivo exato vem na mensagem:

saída real
kubectl -n loja get pod exit-127 -o jsonpath='{.status.containerStatuses[0].state.terminated.message}'
failed to create containerd task: failed to create shim task: OCI runtime create failed:
runc create failed: unable to start container process: error during container init:
exec: "nao-existe": executable file not found in $PATH

Na prática: se você procura 127 no painel e não acha nada, procure 128 com StartError. É o mesmo problema, com a imagem sem o binário ou o caminho errado no command.

137 sem falta de memória

Quando um pod é apagado, o kubelet manda SIGTERM ao processo principal e espera o grace period, 30 segundos por padrão (documentação do Kubernetes, "Pod Lifecycle"), antes de mandar SIGKILL. Um processo que trata o SIGTERM sai logo; um que morre pelo sinal registra 143. Mas o processo principal do container é o PID 1 do namespace, e o Linux não aplica ao PID 1 a ação padrão dos sinais: SIGTERM sem handler é ignorado.

Medimos com o mesmo container (sleep 3600) em dois pods: um em que o sleep é o PID 1 e outro com shareProcessNamespace: true, em que o PID 1 é o processo pause do pod e o sleep não é.

medido
time kubectl -n loja delete pod term-pid1
time kubectl -n loja delete pod term-compartilhado
term-pid1:          kubectl delete levou 32 s; término: 137 Error
term-compartilhado: kubectl delete levou 1 s;  término: 143 Error

O primeiro ignorou o SIGTERM, esperou o grace period inteiro e morreu por SIGKILL: 137, com Reason Error. Em pods de aplicação isso aparece como deploy lento (cada réplica antiga leva 30 s para sair) e conexões cortadas, porque a aplicação nunca soube que ia parar.

A correção é fazer o sinal chegar: tratar SIGTERM na aplicação, ou rodar um init leve como PID 1.

Dockerfile · tini como PID 1 repassando sinais
RUN apk add --no-cache tini
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["node", "server.js"]

avisoSe o ENTRYPOINT é um script de shell que chama a aplicação, use exec no fim do script (exec node server.js). Sem exec, o shell é o PID 1, recebe o SIGTERM e não o repassa.

Perguntas frequentes

Exit code 137 é sempre falta de memória?

Não. 137 é SIGKILL. No nosso teste, um container com sleep como processo principal ignorou o SIGTERM, esperou o grace period de 30 s e morreu com 137 e Reason Error, sem nenhum problema de memória. Falta de memória aparece com Reason OOMKilled.

Por que meu container ignora o SIGTERM?

Porque ele é o PID 1 do container. No Linux, o PID 1 de um namespace não recebe o tratamento padrão de sinais: um SIGTERM sem handler é ignorado. Ou a aplicação trata o sinal, ou um init leve (tini, dumb-init) roda como PID 1 e repassa os sinais.

Onde vejo o exit code?

Em kubectl describe pod, no bloco Last State (container anterior) ou State (atual), ou direto no campo status.containerStatuses[].lastState.terminated.exitCode com -o jsonpath.

Qual a diferença entre Reason Error e Reason Completed?

Completed é exit 0; Error é qualquer código diferente de zero que não tenha um motivo mais específico, como OOMKilled ou StartError.

Leia em seguida

Todos os guias →