Common HTTP Errors When Working with the OpenAI API (and How to Handle Them)

OpenAI’s API is a powerful tool for integrating AI capabilities into applications, but like any external service, it can return errors that developers must handle robustly. In production systems, proper error handling ensures resilience and a smooth user experience even when something goes wrong. This article provides an overview of common HTTP errors encountered with the OpenAI API, explains their causes, and offers best practices (with code snippets) for preventing and mitigating these errors. We assume you’re already familiar with web/API development and will focus on practical guidance for middle and senior engineers.

Understanding HTTP Status Code Categories

Before diving into specific errors, it’s important to understand HTTP status code categories:

  • 2xx – Success: Indicates the request was successfully processed (e.g., 200 OK). When you get a 2xx from OpenAI, your API call succeeded.
  • 4xx – Client Errors: Indicates an issue with the request from the client side. These errors mean the request was invalid or not authorized. The client (your code) might need to modify the request to fix the error.
  • 5xx – Server Errors: Indicates the server (OpenAI’s side) encountered an error or is unavailable. These are generally not caused by your request content, but rather issues on the service side. Clients should implement retries or fallbacks when 5xx errors occur.

By categorizing errors, you can decide which ones require fixing your request vs. which ones just need a retry or other handling.

What the SDK already retries for you

Before writing any retry code, know what the official Python library does on its own. It retries certain failures twice by default, with exponential backoff, and honors Retry-After:

FailureAuto-retried?What you still need to do
Connection errorsYesUsually nothing
408 Request TimeoutYesUsually nothing
409 ConflictYesUsually nothing
429 rate limit (transient)YesUsually nothing
429 billing / spend / usageYes – and that is a problemIntercept before the SDK retries. See the 429 section
500 and aboveYesUsually nothing
422 Unprocessable EntityNoRetry manually, bounded
400, 401, 403, 404NoFix the request

Configure it with max_retries (default 2), globally or per request:

from openai import OpenAI

client = OpenAI(max_retries=0)   # default is 2

# or per-request
client.with_options(max_retries=5).responses.create(
    model="gpt-5.6", input="Hello"
)

Common OpenAI API HTTP Errors and How to Handle Them

Below we cover the most common HTTP error codes from the OpenAI API. For each, we describe typical root causes (specific to OpenAI usage), how to prevent them, best practices for handling, and an example mitigation strategy.

But first of all you can check official documentation on Open AI portal https://developers.openai.com/docs/guides/error-codes

400 Bad Request (Invalid Request)

What it means: A 400 error indicates the request was invalid or malformed. OpenAI returns 400 Bad Request for a variety of issues in your API call. The error response usually includes a message explaining what was wrong (type invalid_request_error). Common causes include missing required parameters, incorrect JSON formatting, using an unsupported parameter name, or sending data that violates limits or policies.

Root Causes (OpenAI-specific):
Missing or invalid parameters: For example, failing to include the model field, or providing a parameter name that doesn’t exist. Using unsupported or invalid parameters can trigger a 400 Bad Request. The exact parameters depend on the API endpoint and model you’re using. Always refer to the current API documentation for supported parameters.[1]
Malformed JSON or request body: If your HTTP request isn’t properly encoded as JSON, or the content type is wrong, the API may not parse it. For instance, forgetting to call json.dumps or to set the Content-Type: application/json header can result in a 400.
Exceeded limits: Sending a prompt or completion that is too large (exceeds the model’s context length or token limit) will be rejected with a 400 error complaining about too many tokens. The error message will usually state that the total number of tokens exceeds the model’s limit and suggest reducing the prompt length[2][3].
Policy violations: If your prompt or input is flagged by OpenAI’s content filters as violating usage policies, the API may return a 400 with a message like ā€œInvalid prompt: your prompt was flagged as potentially violating our usage policy.ā€ In such cases, the request is refused.

How to prevent & fix:
Validate request parameters: Ensure you include all required fields (e.g., model, messages for chat, etc.) and that they follow the correct data types and naming from the OpenAI API documentation. Double-check for typos in parameter names. If the error message points out an unrecognized or missing parameter, fix that in your code.
Check input size: Keep track of token counts for your prompt and expected completion. If there’s a chance you might exceed the model’s context length, consider truncating or splitting the input. Ensure your input and requested output fit within the context window of the model you’re using. Context limits vary by model, so check the current model documentation rather than relying on fixed token limits. You can use utility libraries (like tiktoken for OpenAI models) to count tokens and avoid overflow. If a 400 error reports too many tokens, shorten the prompt or reduce the max_output_tokens requested[3][4] (the Responses API parameter; the older Chat Completions equivalent was max_tokens).
Ensure proper formatting: Always send a well-formed JSON request. In most HTTP libraries, you should serialize your payload to JSON (or use provided client library methods) rather than embedding JSON in a query string. Also set the content type header to application/json. The official SDK handles both for you, which is the simplest way to avoid this class of 400:

from openai import OpenAI

client = OpenAI()

response = client.responses.create(
    model="gpt-5.6",
    input="Hello!"
)
  • Review error messages: The OpenAI API’s error response usually tells you what went wrong in the “message” field. Use that information to adjust your request. For instance, if it says you provided an invalid argument or missing field, correct your code accordingly. If it says your prompt was flagged by policy, you may need to modify the content of your prompt to comply with usage guidelines.

Example – Checking token length before calling the API: Below is a simple example (in Python pseudocode) that checks token length and splits a prompt if it’s too long, to prevent a 400 due to context overflow:

from openai import OpenAI

client = OpenAI()

MAX_INPUT_TOKENS = 100000  # Example only. Use the limit for your selected model.

prompt = generate_user_prompt()

if count_tokens(prompt) > MAX_INPUT_TOKENS:
    prompt = truncate_prompt(prompt, MAX_INPUT_TOKENS)

response = client.responses.create(
    model="gpt-5.6",
    input=prompt,
)

print(response.output_text)

The count_tokens and truncate_prompt would be utility functions you implement to ensure the prompt stays within limits. In practice, such proactive checks can save you from runtime errors and make the application more robust.

401 Unauthorized (Invalid API Key)

What it means: A 401 error indicates your request was not authenticated – the OpenAI API did not accept your API key or token. In other words, the server thinks you’re not authorized to use the API.

Root Causes:
IP not match allowlist: Your request IP does not match the configured IP allowlist for your project or organization

Missing API key: If you forget to include the Authorization: Bearer <API_KEY> header or provide no credentials, the API will reject the call. The error message might say ā€œYou didn’t provide an API keyā€ (sometimes returned as an invalid_request_error in JSON)[5].
Incorrect API key: If the key is present but wrong (e.g. a typo, an extra character, or a key from the wrong organization or project), OpenAI will respond with ā€œIncorrect API key providedā€. This is a common issue when keys are copied incorrectly or not updated in your environment.
Organization ID mismatch: In some cases, if your API request is meant to use a specific organization (OpenAI allows an OpenAI-Organization header or setting), not having the correct org ID can lead to authorization errors. Usually, if your API key is fine, you wouldn’t get 401 for org issues, but ensuring the proper org (if you belong to multiple) is recommended.

Project mismatch: API keys are scoped to Projects. If the key belongs to a different project than the resources you’re accessing, authentication or authorization errors may occur.

How to prevent & fix:
Provide the API key in every request: Always include the correct API key. If using OpenAI’s official libraries, set the API key (e.g. openai.api_key = “sk-…” in Python) before making calls. In raw HTTP calls, include the header. Double-check that the header name and format are correct (“Authorization”: “Bearer YOUR_KEY”).
Verify your API key value: Confirm that the key in your code matches one from your OpenAI account. It’s easy for keys to have trailing spaces or to accidentally use an outdated key. If you see an ā€œIncorrect API keyā€ error, go to your OpenAI account dashboard to copy the active key again and update it[6].
Use environment variables or secure storage: Avoid hardcoding the key. Store it in an environment variable or a secrets manager and load it at runtime. On Linux or macOS, export OPENAI_API_KEY and let the client pick it up automatically:

from openai import OpenAI

client = OpenAI()   # reads OPENAI_API_KEY from the environment

Check organization ID if applicable:* If you have a specific org ID that’s required (some enterprise setups or when using API keys from a different org), make sure to set the OpenAI-Organization header accordingly. Otherwise, the default org for the key is used. The OpenAI authentication guidelines note that you should include the proper organization credentials if required[7].

Example – Setting the API key and handling 401:

import os
from openai import OpenAI
from openai import AuthenticationError

client = OpenAI(
    api_key=os.getenv("OPENAI_API_KEY")
)

try:
    response = client.responses.create(
        model="gpt-5.6",
        input="Hello",
    )

    print(response.output_text)

except AuthenticationError:
    print(
        "Authentication failed. Check your API key, project, and organization settings."
    )

In this snippet, we set the API key from an environment variable. AuthenticationError is raised for a 401. We catch it and log an error (in a real system, you might take further action, such as alerting or falling back to a different mechanism). The OpenAI help center suggests verifying that you are consistently using the correct API key and not mixing up keys between requests[6], as well as ensuring the right organization context[7].

403 Forbidden (Insufficient Permissions)

What it means: A 403 status means the client was recognized (you’re authenticated) but is not allowed to perform that request. With OpenAI, 403 errors are less common in straightforward API usage, but they can occur in specific scenarios.

Root Causes:

– Country, region, or territory not supported.

Your project or organization doesn’t have permission to access the requested model or capability.
Using a model or endpoint you don’t have access to: If you attempt to use a model that your API key is not permitted to use, the API may respond with an error. Often, this actually comes through as a 404 (with a message about the model not existing or no access), but in some contexts it could be 403. For example, if a model is restricted to certain user tiers, your request might be forbidden.

– Where quota errors actually go: Credit, spend-limit, and usage-limit failures return 429, not 403, each with its own error code. See the 429 section. If you are seeing a 403 and suspect billing, you are probably misreading the response – check error.code.

How to prevent & handle:
Use only accessible models and endpoints: Ensure the model name in your request is spelled correctly and that your account has access. If you’re trying out a new model (like a GPT-4 or specialized model), confirm that it’s available to you. Otherwise, you might be hitting a permission issue. Upgrading your plan or requesting access might be necessary for certain models. (If a model is truly not available, you might get a 404; see below.)
Stay within allowed usage: If 403 arises from some usage limit, review your account’s limits. It could be a sign of hitting a hard cap (like a credit limit or a daily spending limit). OpenAI typically signals those as 429 or specific error messages, but double-check your account status if you encounter a mysterious 403.
Review content and parameters: If you suspect a content policy issue, review your prompt for disallowed content and remove or rephrase it. For parameter issues, ensure you’re not using any undocumented endpoints. For example, some administrative endpoints or older API paths might result in a forbidden response if called without proper entitlement.

In practice, if you receive a 403, treat it as a serious refusal – there’s no point in simply retrying a forbidden request without changes. Inspect the error message; it often tells you the reason. For instance, if it’s ā€œRequest forbidden: possible policy violationā€, you must modify the request content. If it’s about access, you may need to choose a different model or obtain access rights.

404 Not Found (Resource or Endpoint Not Found)

What it means: A 404 error means the requested URL or resource was not found on the server. In the context of the OpenAI API, this often happens when the endpoint is correct but the specific resource (such as a model or file ID) does not exist, or if the endpoint itself is wrong.

Root Causes:
Incorrect endpoint URL: A simple but common cause – the URL might be misspelled or the path is wrong. For example, using /v1/completion instead of /v1/completions (missing the ā€œsā€) will yield a 404. Always double-check the base URL and path (it should be https://api.openai.com/v1/… with the correct endpoint path).
Model or resource does not exist (or no access): If you request a model by name and it’s not recognized or not available to you, you’ll get a 404 error with a message like ā€œThe model xyz does not exist or you do not have access to it.ā€ This scenario often occurs when using a model that has been deprecated or a model that your API key isn’t authorized for (e.g., trying a GPT-4 variant without access). The OpenAI error library notes that a 404 indicating ā€œmodel does not exist or access is deniedā€ can happen if the model name is wrong or you lack the required access tier[9][10].
Requesting a non-existent or deleted resource (such as a file, vector store, batch, assistant, or fine-tuning job). OpenAI API has endpoints for retrieving fine-tuning jobs or files. If you call, for example, GET /v1/files/{file_id} with an ID that’s incorrect or already deleted, you will receive a 404.
Wrong HTTP method or route: Occasionally, using the wrong method (GET vs POST) on certain endpoints might result in 404 if that route doesn’t exist. This is less common (usually you’d get a 405 Method Not Allowed), but it’s worth noting.

How to prevent & fix:
Double-check endpoint paths: Typos in the URL are easy to make. Use the official OpenAI API documentation for reference on endpoints. If you’re using an official client library, rely on its methods rather than manual URL construction to avoid mistakes.
Verify model names: Ensure the model name string in your request exactly matches one of the available models. If a model was renamed or a beta model expired, update to a current name. For example, the gpt-4-0314 snapshot was superseded by gpt-4-0613, and both now appear in OpenAI’s deprecation schedule. Pinned snapshot IDs and bare aliases both hard-error once a model is shut down – the alias is removed, not redirected – so check the deprecations page rather than assuming an alias will keep working. A wrong name yields not found. Also confirm that your account has access — if not, either request access or use an available model. This error can also appear when a model is restricted to higher usage tiers and your organization is not in that tier. Check the model’s availability for your account rather than assuming the name is wrong.
Handle resource IDs carefully: When storing IDs (for files, fine-tunes, etc.), ensure you are using the correct ones and they haven’t been deleted. If your app references a file that might be removed, handle the 404 by informing the user or refreshing the list of resources.
Treat 404 as non-retriable: In general, a 404 means something is wrong with the request (not a transient error), so you shouldn’t keep retrying it blindly. Instead, investigate and correct the identifier or URL.

If the error message specifically says the model doesn’t exist or you lack access, the solution is to either correct the model name or gain access. Steps include verifying the name against OpenAI’s model list, checking your account’s access level, and possibly upgrading your plan or contacting OpenAI if you believe you should have access. Summarily, to resolve a model-not-found 404: verify the model name, check your access permissions, use the correct endpoint, and ensure the model is not deprecated[11][12].

Two error taxonomies. OpenAI documents API errors by HTTP status (401, 403, 429, 500, 503) and, separately, the exception types the official Python library raises. They overlap but do not map one-to-one: some SDK exceptions correspond to a status code, and at least one (APITimeoutError) is raised entirely client-side with no HTTP response behind it. The sections below note which is which.

408 Request Timeout and APITimeoutError

What it means:

OpenAI does not list 408 in its API error table. What you will actually hit is APITimeoutError from the official Python library. The docs describe it as your request taking too long to complete, with the server closing the connection.

The distinction matters when debugging. APITimeoutError is raised client-side, by the SDK, when your configured timeout elapses. There is usually no HTTP response to inspect – no status code, no x-request-id, no error body. If you are logging response.status_code in your exception handler, it will not exist. A related but separate case is APIConnectionError, which OpenAI attributes to network settings, proxy configuration, SSL certificates, or firewall rules – that is a failure to reach the servers at all, rather than a failure to answer in time.

Root causes:

  • Client timeout set lower than the request actually needs. Reasoning-heavy calls with high reasoning.effort can run long.
  • Large inputs: long prompts, file inputs, or many tool results in the context.
  • Network path problems between your host and the API, including proxies, egress gateways, or load balancers that terminate slow connections.

How to prevent and fix:

  • Set the timeout explicitly on the client, and set it per-request where a single call is known to be slow.
  • Stream long outputs so you get tokens incrementally instead of waiting on one long response.
  • For genuinely long work, use background mode rather than holding a synchronous connection open.
  • Retry with backoff and jitter. A timeout is transient, so retry is appropriate here, unlike the billing errors covered under 429.
  • Do not raise your client timeout indefinitely to paper over an oversized request. Reduce the request instead.

Example (Python with timeout and retry handling):

import openai
from openai import OpenAI

client = OpenAI(timeout=60.0)

try:
    response = client.responses.create(
        model="gpt-5.6",
        input="Generate a detailed report",
    )
    print(response.output_text)
except openai.APITimeoutError:
    # Raised client-side. No HTTP status or request ID is available here.
    print("Request exceeded the client timeout.")
except openai.APIConnectionError as e:
    # Could not reach the API at all: network, proxy, SSL, or firewall.
    print(f"Could not reach the API: {e}")

409 Conflict and ConflictError

What it means: This is an SDK exception type rather than a status code OpenAI documents in its API error table. The docs describe ConflictError as the resource having been updated by another request, and the recommended fix as retrying the update while making sure no other request is trying to update it at the same time.

That description tells you where this actually shows up: mutable resources, not text generation. Vector stores, files, batches, fine-tuning jobs, containers – anything you create, update, or delete. A responses.create call does not conflict with anything, so a retry loop around one is dead code.

Root causes:

  • Two processes updating the same resource concurrently.
  • A retry firing while the original request is still in flight, so both attempts act on the same resource.
  • An operation issued against a resource whose state has moved on since you read it.

How to prevent and fix:

  • Serialize writes to a single resource with application-level locking, or route them through one worker.
  • Re-read the resource state before updating rather than acting on a stale copy.
  • Retry with a short backoff, but bound it, and treat a repeating conflict as a design problem rather than a transient one.

Example handling:

import random
import time
import openai
from openai import OpenAI

client = OpenAI()

def update_with_conflict_retry(vector_store_id, **fields):
    for attempt in range(3):
        try:
            return client.vector_stores.update(vector_store_id, **fields)
        except openai.ConflictError:
            if attempt == 2:
                raise
            time.sleep(2 ** attempt + random.uniform(0, 0.5))

422 Unprocessable Entity and UnprocessableEntityError

What it means:

Another SDK exception type rather than a documented API status code. OpenAI’s description is deliberately narrow: the request could not be processed despite the format being correct, and the suggested action is simply to try the request again.

That last part is the whole point, and it is why 422 is not just a variant of 400. A malformed request will fail identically forever – retrying it is pointless. A 422 is the API telling you the shape was fine and something else went wrong, which is why the documented remedy is a retry.

Root Causes:

  • A correctly-formed request the endpoint could not act on at that moment.
  • Transient processing failure where the payload itself is valid.

If you can point to a specific wrong field, you are looking at a 400, not a 422.

How to prevent & fix:

Treat it as transient. Retry once or twice with backoff. If it persists on an unchanged request, the request itself is the problem after all – inspect error.message and error.param on the response body, then check the parameter against the API reference for the endpoint you are calling. Log the x-request-id header before you retry; you will need it if you contact support.

Note that a genuinely malformed request – a missing model, an unsupported parameter name, a bad data type – raises BadRequestError (400), not this. See the 400 section above.

Example – retrying a 422, and not retrying a 400:

import random
import time
import openai
from openai import OpenAI

client = OpenAI()

for attempt in range(3):
    try:
        response = client.responses.create(model="gpt-5.6", input="Hello")
        print(response.output_text)
        break
    except openai.UnprocessableEntityError as e:
        request_id = e.response.headers.get("x-request-id")
        print(f"422 on attempt {attempt + 1}, request_id={request_id}")
        if attempt == 2:
            raise
        time.sleep(2 ** attempt + random.uniform(0, 0.5))
    except openai.BadRequestError as e:
        # Malformed request. Retrying will not help - fix the payload.
        print(f"Bad request: {e}")
        raise

429 Too Many Requests (Rate Limit or Quota Exceeded)

What it means: The 429 status indicates you have hit a rate limit or quota limit. The OpenAI API uses 429 for two related scenarios: sending too many requests too quickly (rate limiting), or exceeding your allowed quota (e.g. running out of credits or monthly quota). In either case, the server is refusing to fulfill further requests until conditions reset or you increase your limits.

Root Causes:
Rate limit reached: OpenAI imposes rate limits on requests per minute and tokens per minute for each organization/API key. If you send requests faster than these limits, the API will start returning 429 errors with messages like ā€œRate limit reachedā€. For example, you might see an error message indicating you reached the limit of N requests or tokens per minute for a certain model[13]. Once the minute resets (or a second if they also throttle short-term bursts[14]), requests can succeed again.
Quota exceeded: Even if you aren’t hitting per-minute rate limits, you can get a 429 if you have exhausted your payment quota or free trial credits. In this case, the error message might say ā€œYou exceeded your current quota, please check your plan and billing details.ā€ This means you need to add credits or upgrade your plan to continue. (Note: some systems might alternatively use HTTP 402 for payment required, but OpenAI typically uses 429 with a message for quota issues.)

– Organization usage limits reached (RPM/TPM).

– Billing quota exhausted.

– Project-specific rate limits.

Common error codes:

credit_balance_exhausted, organization_spend_limit_exceeded, project_spend_limit_exceeded, organization_usage_limit_exceeded

How to prevent & manage:
Implement client-side rate limiting: Design your application to respect known rate limits. For instance, if your limit is 60 requests per minute, avoid bursts above 1 request/second. You can use leaky bucket or token bucket algorithms or simpler timers in your code to space out calls.
Monitor usage: Keep an eye on your usage through OpenAI’s dashboard or via the API. If you approach monthly or hard credit limits, either slow down usage or proactively increase your quota (purchase more credits or raise the limit).

Don’t retry billing 429s: Retrying billing, spend, or quota errors won’t restore API access. Update the relevant credits or limits before sending another request. Also: inspect error.code to identify the specific cause; the broader error.type can still be insufficient_quota
Handle 429 with backoff and retries: If a rate limit is hit despite precautions, your code should catch the 429 and wait before retrying. OpenAI recommends exponential backoff for these errors[15]. Exponential backoff means after a 429, wait a short delay and retry, and if it fails again, increase the wait time and try again, and so on. This helps you quickly adapt to the throughput the API will accept[15][14]. Also, since every failed request still counts toward the rate limit, do not hammer retries with no delay[14] (that will only worsen the problem).

Example – Retry with exponential backoff on 429:
Tier 1: configure the client. Before writing any retry code, set the client’s built-in retry behavior. The official SDKs already retry eligible failures and already honor Retry-After. For most applications this is the entire answer, and hand-rolled backoff on top of it is duplicated work with multiplied delay.

from openai import OpenAI

client = OpenAI(max_retries=5, timeout=30.0)

# No retries - useful when your own queue or worker owns retry policy.
no_retry_client = OpenAI(max_retries=0)

Tier 2: separate the retryable 429s from the terminal ones. Not every 429 is a rate limit. Credit balance, spend limit, and usage limit errors also return 429, and retrying them will not restore access – the credits or limits have to be updated first. Check error.code, not error.type, since the broader type can still read insufficient_quota for all of these.

import openai
from openai import OpenAI

client = OpenAI(max_retries=0)

TERMINAL_429_CODES = {
    "credit_balance_exhausted",
    "organization_spend_limit_exceeded",
    "project_spend_limit_exceeded",
    "organization_usage_limit_exceeded",
}

try:
    response = client.responses.create(model="gpt-5.6", input="Hello!")
    print(response.output_text)
except openai.RateLimitError as e:
    code = getattr(e, "code", None)
    if code in TERMINAL_429_CODES:
        # Do not retry. Alert an operator - this needs a billing or limit change.
        raise RuntimeError(f"API access blocked: {code}") from e
    # Genuine rate limit. The client already retried; back off at a higher level.
    raise

Tier 3: add your own retry only when you need behavior the SDK does not provide – a circuit breaker, a dead-letter queue, cross-process coordination, or a longer horizon than a single client call should hold. If you do, set max_retries=0 on the client so the two layers do not compound, and honor Retry-After yourself:

import random
import time
import openai
from openai import OpenAI

TERMINAL_429_CODES = {
    "credit_balance_exhausted",
    "organization_spend_limit_exceeded",
    "project_spend_limit_exceeded",
    "organization_usage_limit_exceeded",
}

client = OpenAI(max_retries=0)  # this layer owns retry policy


def parse_retry_after(exc, cap_seconds=60.0):
    """Return a bounded Retry-After delay, or None if absent or unusable."""
    response = getattr(exc, "response", None)
    if response is None:
        return None
    raw = response.headers.get("retry-after")
    if not raw:
        return None
    try:
        delay = float(raw)
    except (TypeError, ValueError):
        return None          # may be an HTTP-date rather than seconds
    if delay <= 0 or delay > cap_seconds:
        return None          # implausible value - fall back to backoff
    return delay


def call_with_retry(prompt, max_attempts=5):
    for attempt in range(max_attempts):
        try:
            return client.responses.create(model="gpt-5.6", input=prompt)
        except openai.RateLimitError as e:
            if getattr(e, "code", None) in TERMINAL_429_CODES:
                raise                    # billing - retrying cannot fix this
            if attempt == max_attempts - 1:
                raise
            delay = parse_retry_after(e) or 2 ** attempt + random.uniform(0, 1)
            time.sleep(delay)

Additionally, if you find you regularly hit rate limits, you might need to optimize your usage (e.g., batch requests where possible, use caching for repeated queries, etc.) or upgrade your rate limit by contacting OpenAI or increasing your trust tier[17].

500 Internal Server Error (OpenAI server errors)

What it means: A 500 Internal Server Error indicates something went wrong on OpenAI’s side while processing the request. This is a general error for unexpected failures not caused by your input. It could be a bug, an overload, or an internal timeout.

Root Causes:
OpenAI service issues: Often a 500 means the OpenAI servers are experiencing problems – this could be due to high load, an outage, or an unhandled exception on their end. For example, users have reported bursts of 500 errors when OpenAI’s infrastructure is under heavy stress. These errors are usually transient and resolved by OpenAI, but they indicate your request couldn’t be processed at that time[18].
Server-side timeouts or bugs: If your request triggers some internal error (e.g., a model instance crashed or an upstream service failed), you’ll see a 500. Sometimes complex requests or new features can hit edge cases. If the error message says ā€œAn unexpected internal error occurred. Please try again later or contact support if the issue persists.ā€, it’s clearly a server-side problem[19].
Authentication sub-errors: Interestingly, misconfiguration on the server side can also manifest as 500 in some cases. For instance, one analysis noted an auth_subrequest_error could lead to 500, suggesting something in the authentication pipeline failed unexpectedly[20]. However, these are not typical – a well-formed request with a bad API key should yield 401, not 500, so this is likely an edge case or misrouting.
Client-side issues leading to server errors: In general, a bad client request should yield 4xx, not 500. However, if you send a request that technically passes basic validation but causes an error during processing (for example, a function call that the system fails to execute, or a malformed but accepted input that crashes the model), you might encounter a 500. These are rare and often would be considered OpenAI bugs.

How to handle:
Do not panic – usually transient: Treat 500 errors as transient failures. In many cases, simply waiting a moment and retrying the request may succeed. The issue is often out of your control (server overload or glitch). Implement a retry strategy for 500 errors, similar to 429, albeit with perhaps a bit more caution (if a 500 keeps happening, it might not resolve quickly).
Check OpenAI status: If you suddenly see many 500 errors, it could indicate a platform outage or incident. Check OpenAI’s status page (status.openai.com) to see if they reported downtime. This can save time debugging your code when the issue is on the service side.
Ensure request correctness: Although 500 means a server issue, double-check your request isn’t doing something odd. For example, make sure you’re not accidentally sending an extremely large payload or unusual data that might cause internal errors. Ensuring required parameters and correct formats (to avoid any chance of confusing the API) is good practice[21].
Graceful degradation: If an operation fails with 500 and it’s not crucial to retry immediately, implement fallback logic. For instance, if an AI-based suggestion fails, your application might use a cached response or a default behavior instead of hard-failing. This way, a temporary OpenAI issue doesn’t break your whole app.
Contact support if persistent: If you consistently get a 500 on a valid request (especially one that previously worked), it could be a bug with a particular model or endpoint. You may need to reach out to OpenAI support or check community forums to see if others have the issue. Document the error ID or message if provided.

Example – Basic retry on server errors:

import random
import time
import openai
from openai import OpenAI

# max_retries=0 because this function owns the retry policy.
# Leave the default in place if you are not wrapping calls yourself.
client = OpenAI(max_retries=0, timeout=60.0)


def call_with_server_error_retry(prompt, max_attempts=3):
    """Retry transient server-side failures. Client errors are re-raised immediately."""
    for attempt in range(max_attempts):
        try:
            return client.responses.create(model="gpt-5.6", input=prompt)

        except (openai.InternalServerError, openai.APITimeoutError,
                openai.APIConnectionError) as e:
            # Transient: 500-class failures, client timeouts, and network problems.
            if attempt == max_attempts - 1:
                raise

            retry_after = None
            response = getattr(e, "response", None)
            if response is not None:
                retry_after = response.headers.get("retry-after")

            delay = float(retry_after) if retry_after else 2 ** attempt + random.uniform(0, 1)
            request_id = response.headers.get("x-request-id") if response is not None else None
            print(f"Transient failure ({type(e).__name__}), "
                  f"request_id={request_id}, retrying in {delay:.1f}s")
            time.sleep(delay)

        except openai.UnprocessableEntityError as e:
            # 422: format was correct, processing failed. Documented remedy
            # is to retry - and the SDK does NOT do this one for you.
            if attempt == max_attempts - 1:
                raise
            time.sleep(2 ** attempt + random.uniform(0, 1))

        except openai.APIStatusError as e:
            # 400, 401, 403, 404 - retrying will not change the outcome.
            print(f"Non-retryable error {e.status_code}: {e}")
            raise


response = call_with_server_error_retry("Summarize this quarter's incidents.")
print(response.output_text)

This retries transient failures up to three times, honors Retry-After when present, and re-raises anything with a status code, since those need a fix rather than a retry. In production, combine it with logging, alerts, or a circuit breaker. We don’t retry on 4xx (since those are client issues to fix). The delay increases with each attempt. This is a simplistic approach; in production, you might combine this with logging, alerts, or a circuit breaker to avoid spamming a downed service.

502 Bad Gateway

What it means: A 502 indicates an intermediary received an invalid response from an upstream server. Worth stating plainly: 502 and 504 are not in OpenAI’s documented error table, which covers 401, 403, 429, 500 and 503 plus the SDK exception classes. When you see one, it came from a gateway – OpenAI’s own edge, or a proxy, load balancer, or egress gateway on your side of the connection. Check your own network path before assuming it is OpenAI.

Root Causes:
OpenAI server unreachable: The OpenAI server might be down or not responding in time, so the gateway times out or gets a low-level network error. One forum explanation of 502 is that Cloudflare could not reach OpenAI’s backend at all (no response)[22]. This could be due to network partitions or crashes.
Overload or crash leading to invalid response: If OpenAI’s service returns a malformed response or crashes mid-response, the gateway may flag that as invalid. For example, if the connection drops unexpectedly, Cloudflare might return 502.
Client-side network issues (less common): In most cases a 502 for the API will be on the server side, but theoretically a networking issue between you and Cloudflare could cause a similar symptom. However, that usually would manifest as a different error (or no HTTP response at all). So 502 from the API should be read as ā€œserver not reachableā€.

Handling strategies:
Retry with backoff: Like 500 errors, treat 502 as a transient error and retry after a short delay. If the issue was a momentary network blip, the next attempt may succeed. Avoid immediate rapid retries, since if the service is down, spamming won’t help.
Monitor if frequent: An occasional 502 might happen, but if you notice a pattern (e.g., frequent 502s at certain times or with certain request types), investigate further. It could hint at certain operations causing backend issues. You might need to report it or adjust your usage patterns if possible (for instance, if a certain prompt size consistently triggers 502, try smaller chunks).
Fallbacks and circuit breaker: If your system sees a burst of 502/504 errors (see below), that suggests OpenAI is unreachable. A circuit breaker pattern can be useful here: if X consecutive failures occur, you temporarily stop calling the API for some time and serve fallback content or an error message. This prevents overloading your system and OpenAI when it’s likely down. During the open circuit, you can periodically test the API (say after a minute) to see if it’s back up.

To illustrate, one community answer explained 502 as a Cloudflare error meaning the OpenAI servers couldn’t be reached at that moment[22]. In such cases, only a wait and retry will resolve it (the issue resides between Cloudflare and OpenAI).

503 Service Unavailable

Variant 1: “The engine is currently overloaded, please try again later”

What it means: 503 indicates the service is not available to handle the request. This can occur during maintenance or if the servers are overwhelmed and temporarily unable to accept requests.

Variant 2: “Slow Down”

What it means: This one is about your traffic. The documented cause is a sudden increase in your request rate impacting service reliability. The docs explain the mechanism: it occurs with Pay-As-You-Go models, which are shared across all OpenAI users. Your traffic increased significantly, overloading the model, and throttling was applied temporarily to maintain service stability.

Root Causes:
Temporary overload: OpenAI might return 503 if its systems intentionally reject requests due to overload (though 429 is more commonly used for rate limiting). 503 could occur if, say, a certain region of servers is down and no fallback is available, or if a non-critical part of the system (like an optional service) is offline.
Maintenance windows: If OpenAI takes the API down for maintenance (rare, especially without notice), a 503 could be seen. Typically, one would check the status page for such events.

Handling strategies:
Alert/Monitor: If your application receives a 503, it’s a good idea to alert ops or at least log it prominently, because it might indicate a broader outage. It’s not necessarily your code’s fault or something you can fix, but awareness is key (especially if it lasts more than a brief period).
Alternate pathways: In rare cases where you have alternative services (for example, a backup AI service or a cached result), you might switch to those if OpenAI is unavailable. This is an advanced strategy and depends on your application’s tolerance for using a less-powerful model or older data in the interim.

Telling the two apart

Both variants arrive as HTTP 503, so you have to inspect the response before deciding what to do:

import openai
from openai import OpenAI

client = OpenAI(max_retries=0)  # this layer owns 503 policy - see note below

def classify_503(exc):
    """Distinguish 'Slow Down' throttling from ordinary overload."""
    message = str(getattr(exc, "message", "") or exc).lower()
    if "slow down" in message:
        return "slow_down"
    return "overloaded"

try:
    response = client.responses.create(model="gpt-5.6", input="Hello")
    print(response.output_text)

except openai.APIStatusError as e:
    if e.status_code != 503:
        raise

    if classify_503(e) == "slow_down":
        # Do NOT retry on a short backoff. Reduce global throughput and hold.
        rate_governor.throttle(hold_seconds=15 * 60)
        raise
    else:
        # Ordinary overload - transient. Retry with backoff, or check the status page.
        raise

504 Gateway Timeout

What it means: A 504 Gateway Timeout means the upstream server failed to send a response in time. For OpenAI, this often means your request took too long to generate a result, and the Cloudflare gateway timed out waiting for OpenAI’s service.

Root Causes:
Long processing time: Reasoning-heavy requests and large inputs can run for minutes. If something between your application and the API gives up before the response completes, you get a 504. There is no single universal timeout to design around – the limit that bites is whichever intermediary in your path is most impatient. For instance, if you stream a completion but nothing has been sent for a while, the connection could time out.
Server hang or slow response: It could also be that OpenAI’s server got stuck or is under heavy load and couldn’t respond in time. Essentially, 504 is similar to 502 in that the gateway couldn’t get a response, but specifically due to a timeout. One community explanation notes that a 504 usually means ā€œthe server did not receive a timely responseā€[23]. In other words, OpenAI might have started working but didn’t finish in time.
Network latency: Extremely slow network conditions between Cloudflare and OpenAI could, in theory, cause a timeout, but that’s unlikely in their data center environment. It’s more about the service performance.

Handling strategies:
Timeout tuning (if possible): The official SDKs default to a 10-minute request timeout, and OpenAI documents raising it for lengthy prompts. Set it globally or per request:

from openai import OpenAI

client = OpenAI(timeout=900.0)   # 15 minutes, up from the 10-minute default

# or per request
client.with_options(timeout=900.0).responses.create(
    model="gpt-5.6", input=long_document
)

Then audit everything else in the path – your reverse proxy, load balancer, and any serverless function timeout – since those are frequently far shorter than the SDK default and are the actual cause of most 504s. For work that genuinely runs long, use background mode or streaming instead of holding a synchronous connection open.
Simplify or split requests: If certain requests consistently timeout (504), consider if you can simplify them. For example, break a very large task into smaller requests rather than one huge prompt that might take too long.
Retry or alternative approach: As with other server errors, a retry might succeed if the second attempt is faster or hits a more responsive server. However, if the nature of the request is that it’s always slow (e.g., processing a huge document), a direct retry may also time out. In such cases, think about asynchronous processing: perhaps use a smaller model for a first pass, or wait for an official solution if it’s a known limitation.

From a client perspective, 504 is handled similarly to 502 – backoff and retry a couple times. If you get a flurry of 504s, implement a circuit breaker to stop hammering the API until it recovers, and log the events for later analysis.

WebSocket mode errors

The errors above all describe HTTP responses. If you use the Responses API in WebSocket mode, there are two additional error codes that arrive over the open connection rather than as HTTP status codes, which means your existing status-code-based error handling will not catch them.

previous_response_not_found

What it means: The previous_response_id you sent cannot be resolved from the available state.

Why it happens: On an active connection the service keeps one previous-response state in a connection-local in-memory cache – the most recent response. What happens when your ID is not in that cache depends on storage:

  • With store=true, the service may hydrate older response IDs from persisted state. Continuation still works, but you lose the in-memory latency benefit that made WebSocket mode attractive.
  • With store=false, including Zero Data Retention, there is no persisted fallback. An uncached ID returns previous_response_not_found.

Two consequences worth internalizing. First, this is primarily a store=false / ZDR problem, not a reconnect problem – it fires on the second-most-recent ID even on a perfectly healthy connection. Second, a failed turn breaks the chain: when a turn fails with a 4xx or 5xx, the service evicts the referenced previous_response_id from the cache, so an unrelated error poisons your chaining for subsequent turns.

How to handle it: There are three documented recovery paths, in order of preference:

  1. If the prior response is persisted (store=true) and you have a valid ID, continue with previous_response_id plus new input items.
  2. If you compacted context with /responses/compact, use the returned compacted window as the base input for a new response, then append the latest user and tool items.
  3. Otherwise, set previous_response_id to null (or omit it) and send the full input context.

Path 3 is the fallback, and it is why your client must retain enough conversation history locally to rebuild a complete request even when the happy path never uses it.

websocket_connection_limit_reached

What it means: The connection hit its 60-minute limit.

Why it happens: It is a hard cap on connection lifetime, not a symptom of anything going wrong. Any long-lived session – a voice agent, a support session, an always-on assistant – will hit it on a long enough conversation.

How to handle it: Open a new WebSocket connection and continue. Because this is expected rather than exceptional, build for it up front: track connection age, reconnect proactively before the 60-minute mark rather than reacting to the error mid-turn, and carry conversation state across the reconnect. Combined with the previous error, the design rule is the same – state that lives only on one connection is state you will lose.

These arrive as WebSocket error events, not HTTP responses. The payload may include a status field, but your HTTP exception handling will not catch them – APIStatusError and friends never fire. Handle the error event type in your message handler rather than relying on the close code alone.

Debugging and Best Practices in Production

Dealing with API errors is not just about writing retry loops. Robust systems incorporate monitoring, graceful degradation, and preventative measures. Here are some overarching best practices when working with OpenAI’s API in a production environment:

  • Logging and Monitoring: Implement comprehensive logging around your API calls. Log each request, HTTP status code, error message, and the x-request-id response header. The request ID is extremely useful when contacting OpenAI support or debugging intermittent failures. This will help you debug issues by inspecting the error messages returned by OpenAI (which are quite descriptive). Use logging levels to ensure important errors surface in your monitoring tools. Additionally, track metrics: e.g., count of each type of HTTP error over time. If you use APM tools or have dashboards, set up alerts for spikes in 4xx or 5xx errors so you know when something is going wrong (for instance, if many 500/502 errors occur, it could signal an outage).
  • Use OpenAI’s dashboards: OpenAI provides an API usage dashboard where you can see your request counts and token usage. This can help debug issues like 429 errors – you might notice if you’re hitting the rate limit frequently. Also check the OpenAI service status page for any reported outages when encountering server errors[24].
  • Graceful degradation: Always have a plan for when the API call fails. This might mean showing an error message to the user like ā€œSorry, our AI service is busy right now. Please try again later,ā€ rather than a blank screen. Or if the OpenAI API is used for a non-critical feature (say, a summary of content), you could proceed without that feature if the API fails and ensure the rest of the application still works. Graceful handling of failures leads to a better user experience and safer applications.
  • Retry strategies: The SDK already retries connection errors, 408, 409, 429 and 5xx twice by default with exponential backoff, honoring Retry-After. Add your own layer only when you need something it does not provide – a circuit breaker, a dead-letter queue, cross-process coordination – and set max_retries=0 when you do, so the two layers do not compound. Two documented exceptions to “retry transient errors”: billing and spend 429s, which retrying cannot clear, and 503 Slow Down, which needs a sustained rate reduction rather than a backoff. And one gap in the other direction: 422 should be retried but is not auto-retried.
  • Circuit Breaker pattern: In a high-volume system, if OpenAI’s API starts returning errors en masse (e.g., their service is down), a circuit breaker can prevent your system from making pointless calls and saturating resources. The idea is to detect a threshold of failures and then stop calling the API for a short ā€œcool-offā€ period. During that time, you can immediately fail or use a fallback. After the interval, you try one request to test if the service is back. This pattern helps in reducing downstream load and recovering gracefully. Libraries exist for various languages to implement circuit breakers, or you can build a simple one using counters and timestamps.
  • Client-side rate limiting: As mentioned for 429 prevention, consider building a leaky bucket mechanism on your side if you have high traffic. This ensures you queue or reject excess requests instead of having them all hit OpenAI and get rate-limited. Unsuccessful requests can still consume rate-limit capacity, so immediate repeated retries make throttling worse rather than better.
  • Validation and Sanitization: Pre-validate your inputs to the API. This includes checking for things like prompt length (to avoid 400 or 414 URI Too Long if you mistakenly put it in URL), removing or replacing any obviously disallowed content if you have that knowledge (to avoid policy errors), and ensuring data types are correct. By catching issues before sending the request, you reduce the chances of hitting errors and save on API calls.
  • Fallback models or services: If your application can tolerate a quality trade-off, fall back to a cheaper currently supported model rather than an older one. Within the GPT-5.6 family, gpt-5.6-terra targets a balance of capability and cost and gpt-5.6-luna targets efficient high-volume work, so either makes a reasonable fallback from gpt-5.6-sol. Evaluate the fallback on your actual task first – a fallback that returns confidently wrong output is worse than a clean error. Do not fall back to a deprecated model; those return hard errors on shutdown, so your fallback path fails exactly when you need it.
  • Keep dependencies updated: Ensure you’re using the latest version of OpenAI’s API library (if using one) because they often include better error handling or clarify error messages. Also stay updated with OpenAI’s announcements – sometimes error behavior changes (for example, introduction of new error types or changes in rate limits). Being aware of these changes allows you to adjust your error handling accordingly.
  • Regularly test your integration: Over time, your product may evolve and so do the APIs. It’s good to have automated tests or health checks for the OpenAI integration. This could be as simple as a daily cron job that makes a test API call (to a cheap endpoint or a minimal prompt) and alerts if it fails consistently. This can catch issues early (for example, if your API key expired or was revoked, a test would show 401 errors which you can fix before users are affected).
  • Broken link checks for content: As part of overall robustness, ensure that any URLs or links your application relies on are valid. For instance, if you have documentation links or reference links (maybe in error messages or user-facing content) that point to OpenAI or other resources, they should not be broken. Using a tool like Wizardstool can help here. Wizardstool is described as a comprehensive broken link checker that can identify and fix broken inbound and outbound links on your website swiftly. Including such a tool in your maintenance routine helps catch misconfigured endpoints or stale links (for example, if OpenAI changes a documentation URL or if your own API endpoint URLs change in the code, you’d want to catch those 404s). While this isn’t specific to the OpenAI API itself, maintaining healthy links and endpoints is part of a healthy API integration and content validation strategy.

In summary, robust error handling for OpenAI’s API involves both reactive measures (catching errors and responding appropriately) and proactive measures (designing your system to avoid errors and to cope with them when they inevitably occur). By understanding the common HTTP errors and following best practices like the ones above, you can build a resilient integration that provides a smooth experience even in the face of upstream hiccups.

Conclusion

Working with the OpenAI API offers powerful capabilities, but it requires careful attention to error handling and system design. We’ve explored the most common HTTP errors – from client-side issues like 400 and 401 to OpenAI-side issues like 500, 502, 504 – and how to address each of them. To recap, always interpret the status code and error message to decide if the problem is in your request (in which case fix or validate inputs) or on the server side (in which case implement retries and fallbacks). Employ strategies such as exponential backoff for rate limits[15], proper authentication handling[6], and monitoring tools to keep an eye on your usage and any failures.

By building these practices into your application, you’ll ensure that it can handle OpenAI API errors gracefully, keeping your application reliable and your users happy even when something goes wrong. And as a final tip: stay informed with OpenAI’s updates and documentation – the landscape of models and limits can change, and knowing about changes in advance is key to avoiding unexpected errors in the first place. Happy building, and may your API calls be ever successful!


[1] openai.BadRequestError: Error code: 400 – {‘error’: {‘message’: ‘Unrecognized request argument supplied: max_completion_tokens’, ‘type’: ‘invalid_request_error’, ‘param’: None, ‘code’: None}} – Microsoft Q&A

https://learn.microsoft.com/en-us/answers/questions/2139738/openai-badrequesterror-error-code-400-((error-((me

[5] javascript – 400 Error when requesting from OpenAI API – Stack Overflow

https://stackoverflow.com/questions/77928057/400-error-when-requesting-from-openai-api

[6] [7] [24] Incorrect API key provided | OpenAI Help Center

https://help.openai.com/en/articles/6882433-incorrect-api-key-provided

[9] [10] [11] [12] [Solved] The specified model does not exist or access to it is denied.

https://portkey.ai/error-library/model-access-error-10537

[13] [14] [15] [17] How can I solve 429: ‘Too Many Requests’ errors? | OpenAI Help Center

https://help.openai.com/en/articles/5955604-how-can-i-solve-429-too-many-requests-errors

[18] [19] [20] [21] [Solved] An unexpected internal error occurred. Please try again later or contact support if the issue persists.

https://portkey.ai/error-library/internal-error-10513

[22] What is the reason for the error code “Bad Gateway 502”? – API

https://community.openai.com/t/what-is-the-reason-for-the-error-code-bad-gateway-502/471006

[23] API error 504 in call to chatopenai – OpenAI Developer Community

https://community.openai.com/t/api-error-504-in-call-to-chatopenai/292512


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like