Gemini API で 503 エラーが返ってくる
Gemini API を利用中に、突然リクエストが失敗して次のようなエラーが返ってくることがあります。
503 Service Unavailable
{
"error": {
"code": 503,
"message": "The model is overloaded. Please try again later.",
"status": "UNAVAILABLE"
}
}
または
503 Service Unavailable
{
"error": {
"code": 503,
"message": "The service is currently unavailable.",
"status": "UNAVAILABLE"
}
}
コードは問題ないはずなのに、なぜかリクエストが失敗する——この状況は、初めて経験すると戸惑いますが、原因を理解すれば適切に対処できます。ここでは503 エラーが発生する仕組みから、実際のリトライ実装まで丁寧に解説します。
503 エラーが起きる原因
503 エラーは、APIキーやリクエスト形式(400 エラーに相当)の問題ではなく、サーバー側の一時的な問題を示しています。主な原因は以下の通りです。
モデルの過負荷(最多)
Gemini のモデルサーバーに対してリクエストが集中した際に発生します。特に以下の状況で起きやすいです。
- 新機能やモデルのリリース直後(ユーザーが殺到する)
- 平日の昼間など利用者が多い時間帯
- 大規模なバッチ処理が全ユーザーから同時に走るとき
エラーメッセージに "The model is overloaded." と書かれている場合はこのケースです。
サービスメンテナンス・デプロイ
Google が内部でメンテナンスやモデルのアップデートを行う際に、短時間サービスが不安定になることがあります。このケースは通常数分以内に回復します。
ネットワーク経路の問題
クライアント〜Google のデータセンター間のネットワーク経路で問題が発生している場合があります。特定のリージョンやキャリアで起きやすいことがあります。
リージョン固有の問題
Vertex AI 経由で特定リージョンのエンドポイントを指定している場合、そのリージョンのサービスのみ一時的に問題が発生することがあります。
解決手順:ステップバイステップ
Step 1: まず数分待ってリトライする
503 エラーは多くの場合、数秒〜数分待てば自然に解消します。まずは慌てず、30秒〜1分待ってから手動で再実行してみましょう。
Step 2: Google AI のステータスページを確認する
Google Cloud Status Dashboard で、現在の Gemini API / Vertex AI のサービス状態を確認します。「Disruption」や「Outage」の表示がある場合は、Google 側の問題なので回復を待つしかありません。
Step 3: 指数バックオフを実装する(本番必須)
本番アプリケーションには、503 エラーを自動リトライする仕組みが不可欠です。単純なリトライではなく、**指数バックオフ(Exponential Backoff)**を使うことで、サーバーへの負荷を増やさずに回復を待てます。
以下は Python での実装例です。
import google.generativeai as genai
import time
import random
genai.configure(api_key="YOUR_GEMINI_API_KEY")
def call_gemini_with_retry(prompt: str, max_retries: int = 5) -> str:
"""503エラーに対して指数バックオフでリトライする"""
model = genai.GenerativeModel("gemini-2.5-flash")
for attempt in range(max_retries):
try:
response = model.generate_content(prompt)
return response.text
except Exception as e:
error_str = str(e)
# 503エラー(UNAVAILABLE)を検出
if "503" in error_str or "UNAVAILABLE" in error_str or "overloaded" in error_str.lower():
if attempt < max_retries - 1:
# 指数バックオフ: 2^attempt 秒 + ランダムなジッター
wait_seconds = (2 ** attempt) + random.uniform(0, 1)
print(f"⚠️ 503エラー(試行 {attempt + 1}/{max_retries})— {wait_seconds:.1f}秒後にリトライします...")
time.sleep(wait_seconds)
continue
else:
print("❌ 最大リトライ回数に達しました。")
raise
# 503以外のエラーはリトライしない
raise
return "" # ここには到達しない
# 使用例
try:
result = call_gemini_with_retry("Pythonで指数バックオフを実装する方法を教えてください。")
print(result)
except Exception as e:
print(f"最終的なエラー: {e}")期待する出力(成功時):
⚠️ 503エラー(試行 1/5)— 1.4秒後にリトライします...
⚠️ 503エラー(試行 2/5)— 2.8秒後にリトライします...
Pythonで指数バックオフを実装するには...(通常のレスポンス)
Step 4: JavaScript / TypeScript での実装
Node.js や Next.js プロジェクトでも同様の実装ができます。
import { GoogleGenerativeAI } from "@google/generative-ai";
const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY!);
async function callGeminiWithRetry(
prompt: string,
maxRetries: number = 5
): Promise<string> {
const model = genAI.getGenerativeModel({ model: "gemini-2.5-flash" });
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const result = await model.generateContent(prompt);
return result.response.text();
} catch (error: unknown) {
const errorMessage = error instanceof Error ? error.message : String(error);
const is503 =
errorMessage.includes("503") ||
errorMessage.toLowerCase().includes("unavailable") ||
errorMessage.toLowerCase().includes("overloaded");
if (is503 && attempt < maxRetries - 1) {
const waitMs = Math.pow(2, attempt) * 1000 + Math.random() * 1000;
console.warn(
`⚠️ 503エラー(試行 ${attempt + 1}/${maxRetries})— ${(waitMs / 1000).toFixed(1)}秒後にリトライ`
);
await new Promise((resolve) => setTimeout(resolve, waitMs));
continue;
}
throw error;
}
}
throw new Error("最大リトライ回数に達しました");
}Step 5: Vertex AI 使用時のリージョンフォールバック
Vertex AI で特定リージョンに503が続く場合は、別リージョンにフォールバックする方法も有効です。
import vertexai
from vertexai.generative_models import GenerativeModel
REGIONS = ["us-central1", "us-east4", "europe-west4"]
def call_with_region_fallback(prompt: str, project_id: str) -> str:
"""503が続く場合に別リージョンへフォールバック"""
for region in REGIONS:
try:
vertexai.init(project=project_id, location=region)
model = GenerativeModel("gemini-2.5-flash")
response = model.generate_content(prompt)
print(f"✅ リージョン {region} で成功")
return response.text
except Exception as e:
if "503" in str(e) or "UNAVAILABLE" in str(e):
print(f"⚠️ リージョン {region} で503エラー — 次のリージョンへ")
continue
raise
raise RuntimeError("すべてのリージョンで503エラーが発生しました")解決できたか確認する方法
リトライ実装が正しく動作しているか確認するには、意図的に503をシミュレートする方法が便利です。
import unittest
from unittest.mock import patch, MagicMock
class TestGeminiRetry(unittest.TestCase):
def test_retry_on_503(self):
"""503エラーでリトライして最終的に成功するシナリオ"""
mock_model = MagicMock()
# 1回目と2回目は503、3回目は成功
mock_model.generate_content.side_effect = [
Exception("503 UNAVAILABLE: The model is overloaded."),
Exception("503 UNAVAILABLE: The model is overloaded."),
MagicMock(text="成功レスポンス"),
]
with patch("google.generativeai.GenerativeModel", return_value=mock_model):
result = call_gemini_with_retry("テスト", max_retries=3)
self.assertEqual(result, "成功レスポンス")
self.assertEqual(mock_model.generate_content.call_count, 3)
print("✅ テスト合格:503後のリトライが正常に動作しています")
if __name__ == "__main__":
unittest.main()実際の環境では、アプリケーションのログに ⚠️ 503エラー(試行 N/M) のログが出た後に正常なレスポンスが続いていれば、リトライ実装が正しく機能しています。
予防策:再発を防ぐベストプラクティス
1. リトライロジックは最初から組み込む
「初回は成功するから後回し」という考え方は危険です。503 はいつでも起きる可能性があるため、本番コードには最初からリトライロジックを組み込みましょう。
2. ジッターを必ず追加する
複数のクライアントが同時に503を受けてリトライすると、再び同タイミングでリクエストが集中します(「サンダーディングハード」問題)。random.uniform(0, 1) のようなランダムなジッターを待機時間に加えることで、これを防げます。
3. 最大リトライ回数と最大待機時間を設ける
無限ループを防ぐため、最大リトライ回数(推奨: 5〜7回)と待機時間の上限(推奨: 60秒)を設定しましょう。
wait_seconds = min(60, (2 ** attempt) + random.uniform(0, 1))4. エラーログを記録する
503の発生頻度を記録しておくと、サービスの安定性把握や Google へのフィードバックに役立ちます。
5. google-api-core の組み込みリトライを活用する
google-api-core ライブラリには、503 を含む一時的なエラーに対する組み込みのリトライ機能があります。低レベルで実装する前に、retry パラメータの活用も検討してください。
from google.api_core import retry
@retry.Retry(predicate=retry.if_transient_error)
def my_api_call():
# この関数は一時的なエラー(503含む)で自動リトライされる
return model.generate_content("テスト")リトライ戦略の詳細については、Gemini API エラーハンドリング&リトライ完全ガイドも参考になります。また、429 レート制限エラーへの対応は Gemini APIクォータ制限・429エラーの対処法 で詳しく解説しています。
全体を振り返って
Gemini API の 503 エラーは、サーバー側の一時的な過負荷やメンテナンスが原因であり、リトライによって解決できる問題です。重要なポイントをまとめます。
- 503は「一時的なサーバー側の問題」なので、数秒〜数分待てば多くの場合解消する
- 本番アプリには指数バックオフ + ジッターのリトライを最初から実装する
- 最大リトライ回数と最大待機時間の上限を設定し、無限ループを防ぐ
google-api-coreの組み込みリトライ機能も積極的に活用する- 長時間続く場合は Google Cloud Status Dashboard で障害情報を確認する