Claude APIを使った開発やプロダクション運用において、429 Too Many Requests、503 Service Unavailable、そしてタイムアウトエラーに悩まされた経験のある方は多いでしょう。これらのエラーはいずれも「APIが応答しない」という症状をもたらしますが、原因と対処法はそれぞれ異なります。
症状の説明:どんなエラーが起きているか
Claude APIを呼び出した際に遭遇する主なエラーは以下の3種類です。
429 Too Many Requests(レート制限)
anthropic.RateLimitError: 429 {"type":"error","error":{"type":"rate_limit_error","message":"Rate limit exceeded. Please retry after X seconds."}}
リクエストの送信頻度またはトークン消費量がAPIのレート制限(利用上限)を超えた場合に発生します。エラーレスポンスのヘッダーには retry-after が含まれており、何秒後に再試行すべきかが示されます。
503 Service Unavailable(サービス利用不可)
anthropic.APIStatusError: 503 {"type":"error","error":{"type":"overloaded_error","message":"Anthropic's API is temporarily overloaded."}}
Anthropicのサーバーが高負荷状態にある場合に返されます。一時的な問題であり、通常は数秒〜数分で解消されます。
タイムアウト(APIConnectionTimeoutError)
anthropic.APIConnectionTimeoutError: Request timed out after 600000ms
リクエストが指定時間内に完了しなかった場合に発生します。特にClaudeのような大規模言語モデルは長文生成時に時間がかかるため、クライアント側のタイムアウト設定が短すぎると頻発します。
原因の分析:なぜ起きるか
429エラーの原因
① リクエスト数の超過(RPM制限) AnthropicのAPIは利用プランごとに1分あたりのリクエスト数(RPM: Requests Per Minute)が定められています。無料Tier(Free)や低Tier(Tier 1)では制限が厳しく、バースト的な呼び出しで簡単に上限に達します。
② トークン消費量の超過(TPM制限) 1分あたりの入出力トークン合計(TPM: Tokens Per Minute)にも上限があります。長文プロンプトや大量バッチ処理を行うと、RPM制限に達する前にTPM制限に引っかかることがあります。
③ 並列リクエストの超過 同時並行で送信できるリクエスト数にも制限があります。特に非同期処理でPromise.allを使って大量リクエストを一度に送ると発生しやすいです。
503エラーの原因
- Anthropicサーバーの一時的な高負荷・メンテナンス
- モデルのアップデートやデプロイが行われている
タイムアウトの原因
- クライアント側のタイムアウト設定が短すぎる(デフォルト600秒だが環境によって上書きされる)
- 非常に長い出力を要求しているのにmax_tokensが大きい
- ネットワークの不安定性
解決手順:Step by Step
Step 1:エラーの種類を正確に把握する
まず、エラーオブジェクトを適切にキャッチしてログ出力します。
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) {
// 429: レート制限
console.error("Rate limit exceeded:", error.message);
console.error("Retry after:", error.headers?.["retry-after"], "seconds");
} else if (error instanceof Anthropic.APIStatusError) {
// 503など: サーバーエラー
console.error("API status error:", error.status, error.message);
} else if (error instanceof Anthropic.APIConnectionTimeoutError) {
// タイムアウト
console.error("Request timed out:", error.message);
} else {
throw error; // 予期しないエラーは再スロー
}
}Step 2:指数バックオフ(Exponential Backoff)を実装する
429・503エラーに対する最も重要な対策が指数バックオフです。リトライのたびに待機時間を指数的に増やし、サーバーへの負荷を軽減します。
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
/**
* 指数バックオフ付きリトライ関数
* @param fn - 実行する非同期関数
* @param maxRetries - 最大リトライ回数(デフォルト: 3)
* @param baseDelay - 基本待機時間(ms)(デフォルト: 1000ms)
*/
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;
}
// retry-after ヘッダーがあればそれを優先使用
let delay = baseDelay * Math.pow(2, attempt);
if (
error instanceof Anthropic.RateLimitError &&
error.headers?.["retry-after"]
) {
delay = parseInt(error.headers["retry-after"]) * 1000;
}
// ジッター(ランダムな遅延)を加えてリクエストの分散を図る
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");
}
// 使用例
const response = await withRetry(() =>
client.messages.create({
model: "claude-sonnet-4-6",
max_tokens: 1024,
messages: [{ role: "user", content: "こんにちは" }],
})
);
// 期待する出力: リトライが必要な場合は自動的に待機・再試行し、成功時にレスポンスを返すなお、Anthropic公式SDKは
max_retriesオプションを内蔵しており、設定するだけで自動リトライが有効になります。カスタムロジックが不要な場合はSDKのオプションを活用しましょう。
// SDKの組み込みリトライを使う場合
const client = new Anthropic({
maxRetries: 3, // デフォルトは2
});Step 3:レート制限Tierを確認・アップグレードする
Anthropic Console にアクセスし、現在のTierとレート制限を確認します。
主なTierの制限(2026年4月現在・参考値)
- Free: RPM 5 / TPM 25,000
- Tier 1: RPM 50 / TPM 50,000 (最初の$5チャージ後)
- Tier 2: RPM 1,000 / TPM 400,000 ($500の利用後)
- Tier 3: RPM 2,000 / TPM 800,000 ($5,000の利用後)
制限に頻繁にかかる場合は、Anthropic Consoleからのチャージ・利用実績に応じてTierが自動で上がります。もしビジネス要件でより高い制限が必要な場合は、Anthropicのエンタープライズプランへの問い合わせも選択肢です。
Step 4:リクエストを分散・制御する(Concurrency Control)
複数のリクエストを並列で送る際は、同時実行数を制限するキュー機構を導入します。
import Anthropic from "@anthropic-ai/sdk";
import PQueue from "p-queue"; // npm install p-queue
const client = new Anthropic();
// 同時リクエスト数を5に制限し、1秒あたり10リクエストまで
const queue = new PQueue({
concurrency: 5,
intervalCap: 10,
interval: 1000,
});
const prompts = [
"AIの歴史を教えて",
"量子コンピュータとは",
"機械学習の基礎",
// ... 多数のプロンプト
];
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 }],
})
)
)
);
// 期待する出力: レート制限に引っかからずに全リクエストが順次処理されるStep 5:タイムアウトを適切に設定する
長文生成を行う場合は、クライアントのタイムアウト設定を伸ばします。
const client = new Anthropic({
timeout: 60 * 1000, // 60秒(デフォルトは600秒だが環境によって短縮される)
});
// または個別リクエストにタイムアウトを設定(SDK v0.30.0以降)
const response = await client.messages.create(
{
model: "claude-opus-4-6",
max_tokens: 4096,
messages: [{ role: "user", content: "長文レポートを書いてください" }],
},
{
timeout: 120 * 1000, // このリクエストのみ120秒
}
);解決できたかの確認方法
確認手順
- エラーログの監視: エラーが発生しなくなったか、またはリトライ後に成功するかを確認します。
- Anthropic Console のUsage確認:
https://console.anthropic.com/settings/usageでリクエスト数・トークン消費量の推移を確認し、制限に余裕があるかチェックします。 - レスポンスタイムの計測: 以下のコードでレスポンスタイムを計測し、タイムアウトが適切な値かを確認します。
const start = Date.now();
const response = await client.messages.create({
model: "claude-sonnet-4-6",
max_tokens: 1024,
messages: [{ role: "user", content: "テスト" }],
});
const elapsed = Date.now() - start;
console.log(`Response time: ${elapsed}ms`);
// 期待する出力例: Response time: 2340ms- ステータスページの確認: Anthropicのサービスステータスは
https://status.anthropic.com/で確認できます。503エラーが続く場合は、ここで障害情報が公開されていることがあります。
予防策:再発防止のベストプラクティス
1. SDKの組み込みリトライを活用する
Anthropic公式SDKはデフォルトで2回のリトライを内蔵しています。カスタムリトライ実装の前に、まずSDKのオプションを確認しましょう。
const client = new Anthropic({
maxRetries: 4, // 最大4回リトライ(デフォルト: 2)
});2. トークン消費量を事前に見積もる
tiktoken や AnthropicのTokenizerを使って、プロンプトのトークン数を事前に計算し、TPM制限との余裕を把握します。
// シンプルな見積もり(日本語: 約1.5文字/token、英語: 約4文字/token)
function estimateTokens(text: string): number {
const japaneseCharCount = (text.match(/[\u3000-\u9fff]/g) || []).length;
const otherCharCount = text.length - japaneseCharCount;
return Math.ceil(japaneseCharCount / 1.5 + otherCharCount / 4);
}
const prompt = "こんにちは、今日の天気を教えてください";
console.log(`Estimated tokens: ${estimateTokens(prompt)}`);
// 期待する出力例: Estimated tokens: 153. バッチ処理は夜間・低トラフィック時間帯に実行する
レート制限に余裕を持たせるため、大量のバッチ処理は深夜や早朝など、トラフィックが少ない時間帯にスケジュールします。
4. エラー監視・アラートを設定する
本番環境ではDatadog、Sentry、またはCloud Monitoringなどを使い、429/503エラーが一定数を超えたらアラートが来るように設定します。早期検知で対応コストを下げられます。
5. ストリーミングでタイムアウトリスクを下げる
長文生成の場合、ストリーミングAPIを使うとトークンが逐次返るため、クライアント側のタイムアウトが発生しにくくなります。
const stream = await client.messages.stream({
model: "claude-sonnet-4-6",
max_tokens: 4096,
messages: [{ role: "user", content: "詳細な技術仕様書を書いてください" }],
});
// トークンを逐次受け取る
for await (const chunk of stream) {
if (
chunk.type === "content_block_delta" &&
chunk.delta.type === "text_delta"
) {
process.stdout.write(chunk.delta.text);
}
}
// 期待する出力: テキストがリアルタイムで出力される全体を振り返って
Claude APIで発生する429・503・タイムアウトエラーは、適切な対処を知っていれば確実に解決できる問題です。本記事のポイントをまとめます。
- 429(レート制限): 指数バックオフ+ジッターでリトライし、必要に応じてTierをアップグレード。並列リクエストはp-queueなどで制御します。
- 503(サービス過負荷): 同じく指数バックオフでリトライ。
status.anthropic.comで障害情報を確認します。 - タイムアウト: クライアントのタイムアウト設定を伸ばし、長文生成ではストリーミングAPIを活用します。
APIを本番で安定稼働させるためには、エラーハンドリングとリトライロジックの実装が不可欠です。Anthropic SDKの内蔵リトライをベースに、プロダクション要件に合わせてカスタマイズしてみてください。
APIとSDKの詳細については、Anthropic SDKの公式ドキュメントも参考になります。