OpenAI API errors look diverse, but only five layers need to be separated first: did the request leave the client, is the identity correct, are the address and model correct, are the parameters valid, and have quota or rate limits been hit. Troubleshoot in order and most problems can be located within minutes.

This article breaks down 401, 403, 404, 400, 429, and 5xx by status code, with minimal reproduction commands, retry strategy, and a fixed troubleshooting sequence. Model names and gateway configuration are subject to the on-site model pricing and integration documentation.

Note: OpenAI, GPT, and ChatGPT are trademarks of their respective owners. This article uses common API behavior as of October 2026. Error codes and quota rules are subject to official documentation and actual responses.

1. Save three pieces of evidence first

Before troubleshooting, save these three things:

  1. the HTTP status code;
  2. error.type, error.code, and error.message in the response body;
  3. x-request-id in the response headers.

The request ID is the most useful information when talking to the service provider. Without it, you can only describe "a failure at around such-and-such time"; with it, the provider can find the exact request, upstream, and billing.

Status code Common type First judgment
400 invalid_request_error A problem with a parameter, the JSON, or the context length
401 authentication_error The key is missing, wrong, or no longer valid
403 permission_error The key has no access to that model or project
404 not_found_error The Base URL or model name is wrong
429 rate_limit_error / insufficient_quota Rate limiting, or insufficient balance
500/502/503/504 server_error Upstream failure or a network interruption

2. 401 and 403: identity and permission

The core of 401 is "the server does not recognize this key." Common causes:

  • the request header is missing Authorization: Bearer;
  • the key was copied with extra spaces or line breaks, or was truncated;
  • the key was deleted or rotated, or its project was disabled;
  • a gateway key was sent to the official address, or an official key to the gateway address;
  • an environment variable is misspelled, so an empty string is actually sent.

403 is more often "we recognize you, but you are not allowed to do this." For example, the key lacks permission for the model, the organization is restricted, or the project has not enabled the capability. Do not keep retrying on 403; check the key's project and the model permissions in the console.

A quick self-check:

curl -sS "https://api.zhongshangqihang.com/v1/models" \
  -H "Authorization: Bearer $ZSQH_API_KEY" \
  -w "\nHTTP %{http_code}\n"

If it lists models, the key and address are basically correct. If it still returns 401, check the key itself and the environment variable first.

3. 404: address or model does not exist

A 404 does not necessarily mean "the endpoint is retired"; more often the path is wrong. Common cases:

Symptom Cause Fix
404 page not found The Base URL has an extra /v1 or is missing one Use https://api.zhongshangqihang.com/v1 consistently, per the documentation
model_not_found Model name misspelled or not enabled Copy the model name from the model pricing page
404 with a double slash in the path An extra / when joining the URL Remove the duplicate slash
SDK returns 404 base_url repeats the endpoint path Keep only one /v1

When troubleshooting, send a minimal request with curl first to rule out SDK URL-joining problems. If curl works but the SDK does not, the problem is usually in base_url, a proxy, or the SDK version.

4. 400: parameters and context

A 400 means the request itself is invalid; retrying is pointless. Frequent causes include:

  • malformed JSON, such as a trailing comma, single quotes, or an unescaped newline;
  • parameters the model does not support, such as certain sampling parameters on some models;
  • max_tokens above the model limit;
  • input exceeding the context window, returning context_length_exceeded;
  • an image whose format or size is invalid, or whose URL cannot be reached;
  • an invalid tool schema missing required fields.

The order of handling: cut back to the minimal request, then add parameters back one at a time. Do not change five things at once; otherwise, when the error disappears, you will not know which change fixed it.

5. 429: rate limiting or insufficient balance

429 is the most easily misdiagnosed. It has at least two meanings:

Error code Meaning Handling
rate_limit_exceeded Request frequency, token rate, or concurrency exceeded Reduce concurrency, queue requests, use exponential backoff
insufficient_quota Insufficient balance or exhausted quota Top up, change key, check project quota

Look at the response body and headers first. retry-after tells you how long to wait; x-ratelimit-remaining-requests and x-ratelimit-remaining-tokens show how much quota remains. If the remaining amount is zero, backing off longer will not help; you need the window to reset or the limit to be raised.

A usable retry loop:

import random
import time
from openai import OpenAI

client = OpenAI(
    api_key="sk-your-key",
    base_url="https://api.zhongshangqihang.com/v1",
)

def chat(prompt: str, retries: int = 4) -> str:
    for attempt in range(retries):
        try:
            resp = client.chat.completions.create(
                model="gpt-5.5",
                messages=[{"role": "user", "content": prompt}],
                max_tokens=500,
                timeout=60,
            )
            return resp.choices[0].message.content
        except Exception as exc:
            status = getattr(exc, "status_code", None)
            if status not in (429, 500, 502, 503, 504) or attempt == retries - 1:
                raise
            wait = min(2 ** attempt, 16) + random.random()
            print(f"{status}, retrying in {wait:.1f}s: {exc}")
            time.sleep(wait)
    raise RuntimeError("unreachable")

Retrying only helps for 429, 5xx, and network errors. Retrying 400, 401, 403, or 404 only wastes time and quota.

6. 5xx: upstream failures and network problems

500, 502, 503, and 504 usually mean the request was not written incorrectly; the upstream service is abnormal, the gateway timed out, or the network dropped. Principles:

  1. Retry once or twice with exponential backoff and random jitter.
  2. For streaming requests, determine whether partial content has already arrived; partial output may already be billed.
  3. Idempotent operations can retry automatically; non-idempotent operations need a deduplication key.
  4. During a large-scale 5xx incident, check the provider's status page; do not blindly raise concurrency.
  5. Record the request ID so the provider can investigate.

If only your requests return 5xx while other teams are fine, check request body size, timeout settings, and the proxy path first.

7. A fixed troubleshooting sequence

When an error occurs, follow this order without skipping steps:

  1. Send a minimal request with curl to confirm the address and key.
  2. Compare the official and gateway addresses to confirm keys are not mixed up.
  3. Check that the Base URL contains exactly one /v1.
  4. Check that the model name was copied from the pricing page and is enabled.
  5. Remove optional parameters and confirm the minimal request works.
  6. Check the balance, project quota, and key cap.
  7. Check the 429 response headers to distinguish rate limiting from balance.
  8. Check the provider's status page for an upstream outage.
  9. Save the request ID, status code, and response body before contacting support.

8. FAQ

Does a 429 always mean calls are too fast?

No. A 429 may mean frequency or concurrency exceeded, or it may mean insufficient balance. Check error.code and the response headers; do not slow everything down by default.

Does changing the key fix a 401?

Changing the key can rule out a problem with the key itself, but if the address is mixed up, the environment variable is empty, or the project lacks permission, no number of keys will help. First confirm where the request is actually being sent.

Does a 404 mean the model was retired?

In most cases, the Base URL or model name is wrong. Call /v1/models with curl first, then check the model name against the pricing page.

Can 5xx errors be retried indefinitely?

No. Set a maximum retry count and a total timeout to avoid piling up requests during an outage. For streaming requests, also consider that partial output may already be billed.

How do I tell a gateway error from an official error?

Check the response body format and request ID first, then call both the official and gateway addresses with the same key and same model. The layer that reproduces consistently is where the problem lies.

Next steps

Set up the minimal request, usage logging, and retry strategy before sending production traffic. If you need RMB top-ups and a unified multi-model endpoint, start by registering for the ZSQH AI Gateway; model names and prices are subject to model pricing.

Related reading: