ChatGPTやOpenAI APIでupstream connect error or disconnect/reset before headersが表示されたなら、原因はOpenAI側にあります。このメッセージを返しているのは、OpenAIのエッジに配置されたプロキシであるEnvoyです。EnvoyがOpenAIのバックエンドから利用可能な応答を取得できなかったことを示しています。ChatGPTのWeb版では、Error Code 111として表示されることもあります。reset reason:以降の文字列が具体的な診断結果であり、before headersはレスポンスヘッダーが1つも届く前にプロキシが処理を断念した、という意味です。つまり、その503の背後にアプリケーションの実際の応答があるわけではなく、Envoy自身が返したエラーです。OpenAIのインフラそのものを利用者側で直すことはできませんが、ブラウザで起きたのかコード内で起きたのか、そしてreset reasonが何かによって、次に取るべき行動は変わります。
まず状況を分けて考えます:
- ChatGPTのWeb版/アプリ:status.openai.comを確認し、ページを再読み込みするか、新しいセッションを開始します。
- コードから使うOpenAI API:reset reasonを確認し、リクエストIDを記録したうえで、リトライポリシーを適用します。
このエラーが示していること
Envoyは、利用者とOpenAIのバックエンドの間に位置します。リクエストが届くと、Envoyはバックエンドへの接続を開き、リクエストを転送してレスポンスヘッダーを待ちます。この接続が失敗・リセット・タイムアウトしたり、ヘッダーが返る前に容量制限に達したりすると、EnvoyはHTTP 503(場合によっては502)とともにこのメッセージを返します。ChatGPTの障害画面、openai.InternalServerErrorのスタックトレース、エージェントのログなどで見かけるものです。
文言には揺れがあります。retried and the latest reset reasonと書かれている場合、Envoyはすでにリトライしており、その最後の試行が失敗した理由を示しています。いずれにせよ、これはOpenAIのプロキシが、自身のバックエンドから応答を得られなかったと報告している状態です。プロンプトやリクエストボディの問題ではありません。
reset reasonごとの意味と対処
reset reasonを見れば、OpenAIのプロキシで何が起きたか、そしてリトライに意味があるかを判断できます。
| reset reason | OpenAIのプロキシで起きたこと | 利用者側でできること |
|---|---|---|
connection timeout | バックエンドが制限時間内に接続を受け付けられなかった | バックオフを入れてリトライし、ステータスを確認する |
overflow | 容量またはレートの上限に達した(バックエンドが過負荷) | 並行実行数を下げ、バックオフしてからリトライする |
connection failure / remote connection failure | バックエンドに到達できない、または接続を拒否された | リトライする。継続する場合はステータスを確認し、報告する |
connection termination / connection reset | バックエンドがリクエスト途中で接続を閉じた | リトライする。通常は障害発生と重なる |
protocol error | OpenAI側でプロトコル上の問題が起きた | リトライし、続く場合はリクエストIDを添えて報告する |
OpenAIコミュニティの報告では、特に多いのはoverflowとconnection timeoutです。突発的な負荷でバックエンドの容量に達している状況とも整合します。これらはいずれもローカルPCで設定を変えて解決する問題ではありません。ステータス確認、バックオフ、フェイルオーバーが有効な対応です。
ChatGPTのWeb版・アプリで出る場合(Error Code 111)
最初にstatus.openai.comを確認してください。障害が掲載されているなら、基本的には復旧を待つのが解決策です。ただし、アカウント固有の障害が続く場合はサポートへの連絡を検討する価値があります。ステータスが正常でも、ページを再読み込みする、新しいタブを開く、サインアウト後に再ログインすると改善することがあります。古いセッションが切れた接続を保持しているケースがあるためです。ネットワークの切り替え、VPNや社内プロキシの無効化が有効なのは、その中継レイヤーが接続をリセットしている場合に限られます。OpenAIの障害だと決めつける前に、確認しておくとよいでしょう。
コードからOpenAI APIを呼び出している場合
APIでは、このエラーは断続的かつ負荷依存で起こります。openai-pythonのIssueトラッカーでは、毎時数百件のリクエストを送る開発者が、約5%の呼び出しでopenai.InternalServerError: upstream connect error or disconnect/reset before headersが起き、残り95%は成功していたと報告しています。このような部分的な失敗率は、バックエンドの飽和を示唆します。バッチ中心の処理、たとえば大量の埋め込み生成や大規模なドキュメント取り込みでは並行実行数が増えるため、発生しやすくなります。通常はペイロードを変更するよりリトライポリシーを整えるほうが有効ですが、高負荷時には並行数の制御とバッチジョブのキューイングも同じくらい重要です。
問い合わせをエスカレーションする前に、プロバイダー側の問題だと示せる情報を記録しておきましょう。必要なのは、タイムスタンプ、エンドポイントとモデル、HTTPステータスとレスポンス本文、x-request-id、SDKのバージョン、実行中リクエスト数、そして公開済みの障害と失敗時刻が一致するかどうかです。そのうえで、本番運用に耐えるリトライポリシーを適用します。
import random, time
from openai import OpenAI, APIStatusError, APIConnectionError
client = OpenAI()
def with_retry(fn, max_attempts=5, cap=30.0):
for attempt in range(max_attempts):
try:
return fn()
except (APIConnectionError, APIStatusError) as e:
status = getattr(e, "status_code", None)
# retry connection drops and 5xx (incl. this 503); never blindly retry 4xx
if isinstance(e, APIStatusError) and status and status < 500 and status != 429:
raise
if attempt == max_attempts - 1:
raise
retry_after = float(getattr(e, "response", None).headers.get("retry-after", 0)) if getattr(e, "response", None) else 0
backoff = retry_after or min(cap, 0.5 * 2 ** attempt) * (0.5 + random.random())
time.sleep(backoff)
OpenAI SDKには一時的なエラーを自動でリトライする機能があり、max_retriesのデフォルト値は2です。独自のラッパーを重ねる前に、たとえばOpenAI(max_retries=0)のように明示的に設定してください。設定しないとSDK側と独自レイヤー側のリトライが重なります。総試行回数は3〜5回に抑え、全体の並行実行数にも上限を設けましょう。リトライがoverflowを招いたバーストをさらに増幅するのを防ぐためです。429はRetry-Afterに従って処理し、408/409は同じ操作を安全に繰り返せる場合だけリトライします。冪等でない呼び出しやストリーミング呼び出しには注意が必要です。無条件のリトライは処理の重複や、途中まで消費したストリームの再送につながる可能性があります。
クライアント側で見える症状
Envoyが返す503の本文すら受け取れないことも珍しくありません。停止しているエンドポイントに対してcurl -vを実行すると、Request completely sent offの後にcurl: (52) Empty reply from serverが返ることがあります。リクエストは送信されたものの、応答は何も返ってきていない状態です。これに対してEnvoy自身が返すエラーでは、レスポンス本文にupstream connect error...の文字列を含む503が返ります。公開されている報告もこれと一致します。OpenAIのsubredditには、"Network connection lost"とともにretried and the latest reset reason: connection timeoutという完全一致の文言を投稿したユーザーがいます。また、openai-pythonのトラッカーには、高いリクエスト量のもとで同じメッセージがInternalServerErrorとして記録されています。
リトライだけでなく迂回を検討する場面
失敗しているのはOpenAIのゲートウェイとバックエンドの間のホップなので、単一エンドポイントに対して利用者側ができることは、リトライとバックオフに限られます。もう1つの選択肢は冗長化です。あるアップストリームがタイムアウトまたはオーバーフローしたとき、別のバックエンドへフェイルオーバーするレイヤーを経由します。OpenRouterやAIReiterのようなマルチプロバイダーゲートウェイは複数のモデルプロバイダーを前段に置き、遅いプロバイダーを迂回してルーティングします。これはOpenRouterが採用するマルチプロバイダールーティングモデルと同じ考え方です。1つのアップストリームが遅くなったとき、503をそのまま利用者に返す代わりに再ルーティングできる場合があります。もっとも、追加のホップが増えること、ルーター自体の稼働状況に依存すること、料金・データの取り扱い・可観測性に違いがあることは、実際のトレードオフです。それでも、単一プロバイダーの不安定さへの依存は減らせます。
よくある質問
ChatGPTのError Code 111とは何ですか?
一部のChatGPTユーザーは、このメッセージとともに「Error Code 111」という表示を報告しています。OpenAIのプロキシがバックエンドから応答を取得できなかったことを意味する、サーバー側の問題です。status.openai.comを確認してから、ページを再読み込みしてください。
高負荷時やランダムにだけ発生するのはなぜですか?
負荷に応じて発生する障害は、通常、overflow(容量またはレートの上限)か、バックエンドの飽和によって接続時間がタイムアウトを超えた状態を示します。どちらも並行実行数が増えたときにだけ現れるため、同じコードでも大半の時間は正常に動作します。
VPNやファイアウォールが原因になることはありますか?
利用者とOpenAIの間にあるそのレイヤーが接続をリセットしている場合に限られます。ネットワークを切り替えて切り分ける価値はありますが、実際のOpenAI障害やAPI側の503は解決できません。
429のレート制限エラーと同じですか?
いいえ。429は、明示的なレート制限レスポンスを受け取った状態です。この503は、利用可能な応答がそもそも返ってこなかったことを意味します。429ではRetry-Afterに従い、503ではバックオフしてリトライしてください。
"retried and the latest reset reason"は何を意味しますか?
Envoyがすでにリクエストをリトライしており、最後の試行が失敗した理由を表しています。一時的な一度きりの揺らぎではなく、OpenAI側のバックエンドで問題が継続していることを示します。