API do Claude retornou 529 overloaded_error: o que significa e como tratar no seu código

Ilustração de servidor sobrecarregado representando o erro 529 overloaded_error na API do Claude
Resposta rápida

O 529 overloaded_error quer dizer que a API do Claude está temporariamente sobrecarregada por tráfego alto de todos os usuários. Não é limite da sua conta (isso é o 429) nem problema da sua chave. Confira status.claude.com, deixe o retry com backoff do SDK trabalhar (ele já repete 2 vezes por padrão), limite as tentativas e registre o request_id sem gravar segredos.

Fala aí, beleza? Teu script, integração ou agente estava rodando liso e do nada a API da Anthropic devolveu um 529 com overloaded_error no meio do caminho 😅

Este post é pra quem programa contra a API: bora ler o corpo do erro, separar o 529 dos erros parecidos e tratar a falha direito no código

O que a mensagem 529 overloaded_error diz e o que ela não diz

Ela diz uma coisa só: a API está sobrecarregada agora, de forma temporária

Na documentação oficial de erros a definição é literal: 529 - overloaded_error: The API is temporarily overloaded. E tem um detalhe importante: o 529 pode acontecer quando a API recebe tráfego alto vindo de TODOS os usuários

Os erros sempre voltam em JSON, nesse formato:

{
  "type": "error",
  "error": {
    "type": "overloaded_error",
    "message": "..."
  },
  "request_id": "req_..."
}

E o que dá pra concluir disso?

  • A sobrecarga é temporária
  • O problema está do lado da API, não do seu

E o que ela NÃO diz:

  • Que sua API key está errada
  • Que seu código está quebrado
  • Que você estourou a cota da sua organização (isso tem código próprio, o 429)

Tome cuidado com um detalhe: a documentação só confirma o cabeçalho retry-after no 429. Então não escreva código que dependa de retry-after pra decidir quanto esperar no 529

Outra coisa que vale ouro: toda resposta da API traz o cabeçalho request-id com um identificador único (algo como req_018EeWyXxfu5pfWkrYcMdjWG). Ele também aparece no corpo do erro como request_id, e é esse valor que você informa ao suporte se precisar abrir chamado

529, 429, 500, 504 ou erro de rede: como diferenciar

O jeito mais rápido é olhar o status HTTP e o error.type. Cada um aponta pra um culpado diferente

Situação Tipo do erro O que significa Exceção no SDK Python
529 overloaded_error API sobrecarregada por tráfego geral InternalServerError (status >=500)
429 rate_limit_error Sua organização atingiu um rate limit; a resposta informa qual limite foi excedido e traz retry-after RateLimitError
500 api_error Erro interno inesperado nos sistemas da Anthropic InternalServerError
504 timeout_error A requisição expirou durante o processamento InternalServerError (status >=500)
Sem status HTTP falha de conexão Rede ou timeout do lado do cliente APIConnectionError

Todas as exceções com status 4xx/5xx no SDK Python são subclasses de anthropic.APIStatusError, que expõe status_code e response. Então dá pra separar o 529 do 500 checando o status_code

E quando o problema é o 429, os limites são medidos em três eixos: requisições por minuto (RPM), tokens de entrada por minuto (ITPM) e tokens de saída por minuto (OTPM)

No 504, a própria documentação recomenda usar streaming na Messages API em requisições longas

Overloaded no streaming: quando o erro chega depois do 200

Sintoma clássico: a resposta começou com 200, os tokens foram chegando e o stream quebrou no meio

Que status é esse então? Nenhum 529 😛

Em respostas por streaming (SSE), um erro pode acontecer depois que a API já devolveu 200. Sob carga alta, o overloaded_error pode chegar como evento SSE error, e não como status 529. O evento é assim:

event: error
data: {"type": "error", "error": {"type": "overloaded_error", "message": "Overloaded"}}

A solução é o código que consome o stream também reconhecer esse evento. Exemplo didático de como isso fica num leitor de eventos que você já tenha parseado:

import json

def tratar_evento(nome_evento, dados_brutos):
    if nome_evento == "error":
        dados = json.loads(dados_brutos)
        tipo = dados["error"]["type"]
        if tipo == "overloaded_error":
            # mesma estratégia do 529: retry com backoff e limite
            raise RuntimeError("overloaded_error no meio do stream")
        raise RuntimeError(f"erro no stream: {tipo}")
    # ... processa os demais eventos normalmente

Erro comum aqui: tratar só o código 529 na resposta HTTP e deixar o erro do stream passar batido. Aí tua aplicação entrega uma resposta cortada pela metade como se estivesse tudo certo

Antes de mexer no código: confira o status oficial

Antes de sair refatorando tudo, faz o diagnóstico por eliminação, do provedor pro seu lado:

  1. Abra o status.claude.com, a página oficial de status da Anthropic. Ela acompanha separadamente claude.ai, a API do Claude e o Claude Code. Se tiver incidente na API, a causa provável está no provedor e mexer no código não resolve
  2. Se o status estiver normal e o erro for 429, a causa está nos limites da sua organização (RPM, ITPM ou OTPM). Aí o ajuste é no seu ritmo de chamadas, respeitando o retry-after
  3. Se for falha de conexão, sem status HTTP nenhum, verifique a sua rede antes de culpar a API

Pra prevenir: assine as atualizações da página de status. Assim você fica sabendo do incidente antes do seu usuário reclamar haha

Como tratar o 529 no código: retry, backoff e limite de tentativas

A boa notícia é que boa parte já vem pronta

Os SDKs oficiais de Python e TypeScript repetem automaticamente, 2 vezes por padrão e com backoff exponencial curto, os erros de conexão, 408, 409, 429 e status >=500. O 529 entra nesse grupo

O número de retentativas é configurável. No Python, no cliente inteiro ou por requisição:

from anthropic import Anthropic

# vale para todas as chamadas deste cliente
client = Anthropic(max_retries=4)

# vale só para esta chamada
client.with_options(max_retries=1).messages.create(**params)

No TypeScript a opção se chama maxRetries:

import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic({ maxRetries: 4 });

Com valor 0, as retentativas ficam desligadas. E no SDK TypeScript o timeout padrão das requisições é de 10 minutos, configurável pela opção timeout

Se tu quiser controlar o retry na mão (pra logar cada tentativa, por exemplo), desliga o retry do SDK e faz o seu com teto. Exemplo didático, não é teste executado:

import time
import anthropic

client = anthropic.Anthropic(max_retries=0)  # retry fica só no nosso loop

MAX_TENTATIVAS = 4

def chamar_com_backoff(params):
    for tentativa in range(MAX_TENTATIVAS):
        try:
            return client.messages.create(**params)
        except anthropic.APIStatusError as e:
            if e.status_code != 529 or tentativa == MAX_TENTATIVAS - 1:
                raise
            espera = 2 ** tentativa  # 1s, 2s, 4s...
            time.sleep(espera)

Os valores de tentativas e espera aí são escolha sua, a documentação não define um número oficial pro 529

Erro comum (e já vi muita gente cair nisso): empilhar um retry próprio, sem limite, em cima do retry do SDK. Cada tentativa sua vira até 3 chamadas (a original mais as 2 do SDK), e num momento de sobrecarga tu só ajuda a afogar ainda MAIS a API. Ou desliga um, ou limita os dois

Fallback de modelo e log seguro sem vazar chaves

Quando as tentativas acabam, alguma coisa precisa acontecer. Aí entra uma decisão de arquitetura sua, não uma recomendação da Anthropic:

  • Trocar pra outro modelo que você já deixou configurado como reserva
  • Responder com degradação controlada ("tente de novo em instantes", fila pra processar depois e por aí vai)

Não existe garantia de que outro modelo vai estar menos sobrecarregado, então trate o fallback como plano B, não como cura

No log, grave o que ajuda a investigar e nada que vaze segredo:

  • Grave: status_code, error.type, error.message e request_id
  • Nunca grave: a API key, os headers de autenticação e o conteúdo sensível dos prompts

Exemplo didático:

import logging
import anthropic

log = logging.getLogger("claude")

def logar_erro(e: anthropic.APIStatusError):
    corpo = e.response.json()
    log.error(
        "erro na API do Claude",
        extra={
            "status_code": e.status_code,
            "error_type": corpo.get("error", {}).get("type"),
            "error_message": corpo.get("error", {}).get("message"),
            "request_id": corpo.get("request_id"),
        },
    )

Repara que o log não toca em headers de requisição nem nos messages enviados. Só o necessário pra você (ou o suporte) achar a chamada depois

Pra prevenir dor de cabeça:

  • Centralize retry, fallback e log num único wrapper. Se você usa IA pra montar a integração, vale pedir isso explicitamente quando for integrar uma API externa com o Claude Code
  • Use streaming em requisições longas, como a documentação recomenda pra evitar timeout
  • Se o mesmo contexto grande se repete entre chamadas, vale entender como funciona o cache de prompt na Claude API

Vídeo do canal sobre o ecossistema Claude

Pra quem trabalha com Claude no dia a dia, esse conteúdo do canal mostra um jeito de usar o Claude Code em que o Opus coordena o trabalho e o Haiku executa as tarefas 🙂

Conteúdo complementar do Hora de Codar para conhecer o canal; não é uma demonstração específica desta notícia ou versão.

Próximo passo: deixe sua integração pronta para o próximo 529

Separei um checklist curto pra rodar ainda hoje:

  1. Revise o max_retries (Python) ou maxRetries (TypeScript) e confirme que não tem retry próprio sem limite por cima
  2. Garanta que o handler de streaming trata o evento error com overloaded_error
  3. Force um erro em ambiente de teste e confira se o log gravou o request_id sem nenhuma chave ou prompt sensível
  4. Assine as atualizações do status.claude.com

Até o próximo post! =)

Perguntas frequentes

Por que recebo 529 overloaded_error mesmo mandando poucas requisições?

Porque o gatilho não é o seu volume: o 529 pode acontecer quando a API recebe tráfego alto vindo de todos os usuários. Então até uma integração com pouquíssimas chamadas pode tomar o erro, e o caminho é o retry com limite, não reduzir ainda mais o seu ritmo.

Qual exceção pegar no SDK Python pra tratar só o 529?

O InternalServerError cobre qualquer status >=500, então ele junta 529, 500 e 504 no mesmo balaio. Pra isolar o 529, capture anthropic.APIStatusError e confira se o status_code é 529. E no streaming lembre que o overloaded_error pode vir como evento error, sem status 529 nenhum.


Quer aprender mais sobre inteligência artificial e programação na prática? Conheça o canal Hora de Codar no YouTube e acompanhe os próximos vídeos.

Escrito por | Matheus Battisti

Matheus Battisti
Fundador da Hora de Codar

Programador apaixonado pelo mundo das tecnologias, sempre buscando em aprender e se aprofundar em linguagens, frameworks e o que mais for necessário para executar um bom trabalho. Agora tem uma nova missão que é de passar seu conhecimento adiante para formar novos programadores e especializar mais os que já são.

Subscribe
Notify of
guest

0 Comentários
Oldest
Newest Most Voted

Formações

Formação Vibe Coding

Formação Vibe Coding

Do Prompt ao Produto: Crie Software Real com IA

  • 474 aulas
  • 20 projetos
  • 39h 30min

Blog | Mais populares