◉CLAUDE LABJP
●2.1.301 — Adds the vim % motion, LaTeX math rendering in the VS Code panel, and a retry-watchdog limit for usage-limit waits (10/15)●2.1.299 — Conversations over 200K tokens left idle about 54 minutes get compacted; MCP allow rules now match only the server they name●SONNET 4.5 — Retires on the Claude API on 11/30, 45 days left. Migrate to Sonnet 5.5●WINDOWS — Reports say hooks break silently only on Japanese-locale Windows; check the character encoding first●FAST MODE — Opus 5.5 fast mode is out of research preview and no longer needs the beta header (10/15)●NEW — I Put a Ten-Line Promise File at the To…●2.1.301 — Adds the vim % motion, LaTeX math rendering in the VS Code panel, and a retry-watchdog limit for usage-limit waits (10/15)●2.1.299 — Conversations over 200K tokens left idle about 54 minutes get compacted; MCP allow rules now match only the server they name●SONNET 4.5 — Retires on the Claude API on 11/30, 45 days left. Migrate to Sonnet 5.5●WINDOWS — Reports say hooks break silently only on Japanese-locale Windows; check the character encoding first●FAST MODE — Opus 5.5 fast mode is out of research preview and no longer needs the beta header (10/15)●NEW — I Put a Ten-Line Promise File at the To…
Articles/API & SDK
⬡ API & SDK/2026-04-07Intermediate

How to Fix Claude API 429, 503 Errors and Timeouts: A Complete Troubleshooting Guide

Struggling with Claude API 429 rate limit errors, 503 service unavailable responses, or timeout failures? This guide covers root causes and step-by-step fixes including exponential backoff, concurrency control, and Tier upgrades.

troubleshooting92error17fix12api39rate-limit74295503timeout10

If you've been building with the Claude API, chances are you've hit at least one of these errors: 429 Too Many Requests, 503 Service Unavailable, or a frustrating timeout that kills your request mid-flight. These errors share a common symptom — the API isn't responding — but each has distinct causes and fixes.

Understanding the Symptoms

429 Too Many Requests (Rate Limit Exceeded)

anthropic.RateLimitError: 429 {"type":"error","error":{"type":"rate_limit_error","message":"Rate limit exceeded. Please retry after X seconds."}}

This error fires when your application exceeds the API's rate limits — either by sending too many requests per minute (RPM), consuming too many tokens per minute (TPM), or hitting the concurrent request ceiling. The response typically includes a retry-after header telling you exactly how long to wait.

503 Service Unavailable (Server Overload)

anthropic.APIStatusError: 503 {"type":"error","error":{"type":"overloaded_error","message":"Anthropic's API is temporarily overloaded."}}

A 503 means Anthropic's servers are temporarily under heavy load. This is usually short-lived — anywhere from a few seconds to a couple of minutes. It's not caused by anything you're doing wrong; it's a capacity issue on the server side.

APIConnectionTimeoutError (Request Timeout)

anthropic.APIConnectionTimeoutError: Request timed out after 600000ms

Your request didn't complete within the allowed time window. This is especially common with large language models when generating long outputs. If your environment has a shorter timeout than the SDK default (600 seconds), you'll see this more often than expected.

Why These Errors Occur

429 — Three Root Causes

① Exceeding RPM (Requests Per Minute) Every Anthropic API tier has an RPM ceiling. Free-tier and Tier 1 accounts have tight limits that can be hit quickly during burst traffic — for example, when multiple users trigger requests simultaneously.

② Exceeding TPM (Tokens Per Minute) Your token budget resets each minute. Long prompts, large outputs, or high-volume batch jobs can drain your TPM allowance before the minute is up, causing 429s even when RPM looks fine.

③ Too Many Concurrent Requests Running large parallel workloads with Promise.all without rate control is a common culprit. The API enforces a concurrent request limit per account.

503 — Server-Side Issues

503 errors come from Anthropic's infrastructure, not your code. They're caused by peak traffic, rolling deployments, or temporary capacity constraints. Check https://status.anthropic.com/ to see if there's an active incident.

Timeouts — Client-Side Misconfiguration

Timeouts happen when the client gives up before the server responds. The SDK default is 600 seconds, but proxy servers, serverless function limits (e.g., Vercel's 10-second cap on Hobby plans), or custom timeout configurations can cut this short.

Step-by-Step Fixes

Step 1: Identify the Exact Error

Before fixing anything, make sure you're catching and classifying errors properly:

import Anthropic from "@anthropic-ai/sdk";
 
const client = new Anthropic();
 
try {
  const message = await client.messages.create({
    model: "claude-opus-4-6",
    max_tokens: 1024,
    messages: [{ role: "user", content: "Hello" }],
  });
  console.log(message.content);
} catch (error) {
  if (error instanceof Anthropic.RateLimitError) {
    console.error("Rate limit hit:", error.message);
    console.error("Retry after:", error.headers?.["retry-after"], "seconds");
  } else if (error instanceof Anthropic.APIStatusError) {
    console.error("Server error:", error.status, error.message);
  } else if (error instanceof Anthropic.APIConnectionTimeoutError) {
    console.error("Timeout:", error.message);
  } else {
    throw error; // re-throw unexpected errors
  }
}

Step 2: Implement Exponential Backoff with Jitter

Exponential backoff is the single most effective fix for both 429 and 503 errors. The idea: each retry waits twice as long as the previous one, with a small random offset (jitter) to spread out burst retries from multiple clients.

import Anthropic from "@anthropic-ai/sdk";
 
const client = new Anthropic();
 
/**
 * Retries an async function with exponential backoff + jitter
 */
async function withRetry<T>(
  fn: () => Promise<T>,
  maxRetries = 3,
  baseDelay = 1000
): Promise<T> {
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    try {
      return await fn();
    } catch (error) {
      const isRetryable =
        error instanceof Anthropic.RateLimitError ||
        (error instanceof Anthropic.APIStatusError && error.status === 503) ||
        error instanceof Anthropic.APIConnectionTimeoutError;
 
      if (!isRetryable || attempt === maxRetries) {
        throw error;
      }
 
      // Respect the retry-after header if present
      let delay = baseDelay * Math.pow(2, attempt);
      if (
        error instanceof Anthropic.RateLimitError &&
        error.headers?.["retry-after"]
      ) {
        delay = parseInt(error.headers["retry-after"]) * 1000;
      }
 
      // Add jitter to avoid thundering herd
      const jitter = Math.random() * 500;
      const totalDelay = delay + jitter;
 
      console.warn(
        `Attempt ${attempt + 1} failed. Retrying in ${Math.round(totalDelay)}ms...`
      );
      await new Promise((resolve) => setTimeout(resolve, totalDelay));
    }
  }
  throw new Error("Max retries exceeded");
}
 
// Usage
const response = await withRetry(() =>
  client.messages.create({
    model: "claude-sonnet-4-6",
    max_tokens: 1024,
    messages: [{ role: "user", content: "Hello!" }],
  })
);
// Expected: Automatically retries on failure, returns response on success

Tip: The Anthropic SDK has built-in retry support. If you don't need custom logic, use maxRetries directly:

const client = new Anthropic({
  maxRetries: 3, // Default is 2
});

Step 3: Check and Upgrade Your Rate Limit Tier

Visit https://console.anthropic.com/settings/limits to see your current Tier and limits.

Approximate Tier limits (as of April 2026):

  • Free: 5 RPM / 25,000 TPM
  • Tier 1: 50 RPM / 50,000 TPM (after first $5 deposit)
  • Tier 2: 1,000 RPM / 400,000 TPM (after $500 in usage)
  • Tier 3: 2,000 RPM / 800,000 TPM (after $5,000 in usage)

Tier upgrades happen automatically as your usage grows. For enterprise-level limits, contact Anthropic directly.

Step 4: Add Concurrency Control for Parallel Requests

If you're sending many requests in parallel, use a queue to cap concurrency:

import Anthropic from "@anthropic-ai/sdk";
import PQueue from "p-queue"; // npm install p-queue
 
const client = new Anthropic();
 
// Max 5 concurrent requests, max 10 per second
const queue = new PQueue({
  concurrency: 5,
  intervalCap: 10,
  interval: 1000,
});
 
const prompts = [
  "Explain quantum computing",
  "What is machine learning?",
  "History of the internet",
  // ... many more prompts
];
 
const results = await Promise.all(
  prompts.map((prompt) =>
    queue.add(() =>
      client.messages.create({
        model: "claude-haiku-4-5-20251001",
        max_tokens: 512,
        messages: [{ role: "user", content: prompt }],
      })
    )
  )
);
// Expected: All requests complete without triggering rate limits

Step 5: Fix Timeout Issues

For long-running generations, extend the timeout configuration:

// Client-level timeout
const client = new Anthropic({
  timeout: 120 * 1000, // 120 seconds
});
 
// Per-request timeout (SDK v0.30.0+)
const response = await client.messages.create(
  {
    model: "claude-opus-4-6",
    max_tokens: 4096,
    messages: [{ role: "user", content: "Write a detailed technical report" }],
  },
  {
    timeout: 180 * 1000, // 180 seconds for this request only
  }
);

For long outputs, streaming is often a better solution than increasing timeout values:

const stream = await client.messages.stream({
  model: "claude-sonnet-4-6",
  max_tokens: 4096,
  messages: [{ role: "user", content: "Write a detailed technical spec" }],
});
 
for await (const chunk of stream) {
  if (
    chunk.type === "content_block_delta" &&
    chunk.delta.type === "text_delta"
  ) {
    process.stdout.write(chunk.delta.text);
  }
}
// Expected: Text streams in real-time, timeout risk is eliminated

Verifying the Fix

Once you've applied your changes, confirm everything is working:

  1. Monitor error logs: 429s should be handled by retries and no longer bubble up as unhandled exceptions.

  2. Check Usage in Console: Visit https://console.anthropic.com/settings/usage and verify RPM/TPM usage stays comfortably below your tier ceiling.

  3. Measure response time:

const start = Date.now();
const response = await client.messages.create({
  model: "claude-sonnet-4-6",
  max_tokens: 1024,
  messages: [{ role: "user", content: "Test" }],
});
const elapsed = Date.now() - start;
console.log(`Response time: ${elapsed}ms`);
// Expected output: Response time: 1800ms (will vary)
  1. Check Anthropic Status: If 503s persist, check https://status.anthropic.com/ for active incidents.

Prevention: Long-Term Best Practices

Use SDK Built-in Retries as Your First Line of Defense

Before writing custom retry logic, set maxRetries on your SDK client. It handles the most common cases out of the box.

Estimate Token Usage Before Sending

Use Anthropic's Tokenizer or a lightweight estimation function to predict token consumption before sending batches.

function estimateTokens(text: string): number {
  // Rough estimate: ~4 chars per token for English
  return Math.ceil(text.length / 4);
}
 
const prompt = "Explain the concept of neural networks";
console.log(`Estimated tokens: ${estimateTokens(prompt)}`);
// Expected output: Estimated tokens: 10

Schedule Batch Jobs During Off-Peak Hours

If you're running large batch workloads, schedule them during nights or weekends when API traffic is lower and you have more headroom before hitting limits.

Set Up Error Monitoring and Alerts

In production, integrate with Sentry, Datadog, or your preferred monitoring platform. Alert when 429/503 error rates exceed a threshold — catching the problem early is far cheaper than debugging it after customers complain.

Looking back

Claude API errors — 429, 503, and timeouts — are manageable with the right patterns in place. Here's the quick-reference summary:

  • 429 (Rate Limited): Use exponential backoff with jitter, respect retry-after headers, control concurrency with a queue, and upgrade your Tier if needed.
  • 503 (Server Overload): Same backoff strategy applies; check status.anthropic.com for incident updates.
  • Timeouts: Extend client timeout settings, use streaming for long outputs, and check for serverless platform limits.

The Anthropic SDK's built-in maxRetries option covers most cases. Layer in custom backoff and concurrency control for production workloads where reliability matters.

Share

Thank You for Reading

Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

⟐ Claude Code2026-05-02
Stop the 'old_string is not unique' Error in Claude Code's Edit Tool — A Practical Rewrite Strategy
When Claude Code's Edit tool throws 'old_string is not unique in the file', the root cause is usually that the prompt didn't guarantee a uniquely identifiable target. Here's how to design rewrites that actually stick.
⬡ API & SDK2026-10-16
Sending 40 Rows From Make to the Claude API Stops at Row 14 — Avoiding the 429 With One Subtraction
Why a no-code automation that sends spreadsheet rows to the Claude API one by one hits a 429 partway through, and how to fix it. Seven spacing strategies tested on a mock bucket, a formula for the Sleep delay, and settings that stop failed rows from vanishing.
⬡ API & SDK2026-10-14
A 429 With retry-after: 120 Makes the Anthropic SDK Try to Wait 120 Seconds
I ran the Anthropic SDK's automatic retries against a mock server in 12 scenarios. Two retries by default, retry-after obeyed with no cap, and spend-limit 429s that no amount of waiting fixes. Code for a retry wrapper with a wait cap and a time budget, plus the logs.