Overview
The OpenAI Python SDK provides a hierarchy of exception classes to help you handle different error scenarios. All exceptions inherit from openai.APIError.
Exception Hierarchy
OpenAIError
├── APIError
│ ├── APIConnectionError
│ │ └── APITimeoutError
│ ├── APIResponseValidationError
│ └── APIStatusError
│ ├── BadRequestError (400)
│ ├── AuthenticationError (401)
│ ├── PermissionDeniedError (403)
│ ├── NotFoundError (404)
│ ├── ConflictError (409)
│ ├── UnprocessableEntityError (422)
│ ├── RateLimitError (429)
│ └── InternalServerError (5xx)
├── LengthFinishReasonError
├── ContentFilterFinishReasonError
└── InvalidWebhookSignatureError
Basic Error Handling
import openai
from openai import OpenAI
client = OpenAI()
try:
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "Hello!"}],
)
except openai.APIConnectionError as e:
print("The server could not be reached")
print(e.__cause__) # an underlying Exception, likely raised within httpx.
except openai.RateLimitError as e:
print("A 429 status code was received; we should back off a bit.")
except openai.APIStatusError as e:
print("Another non-200-range status code was received")
print(e.status_code)
print(e.response)
Exception Classes
APIConnectionError
Raised when the SDK cannot connect to the API.
Attributes:
message (str) - Error description
request (httpx.Request) - The request that failed
import openai
from openai import OpenAI
client = OpenAI()
try:
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "Hello!"}],
)
except openai.APIConnectionError as e:
print(f"Connection failed: {e.message}")
print(f"Request URL: {e.request.url}")
# Underlying exception (e.g., network error)
print(f"Cause: {e.__cause__}")
APITimeoutError
Raised when a request times out. Inherits from APIConnectionError.
import openai
from openai import OpenAI
client = OpenAI(timeout=5.0) # 5 second timeout
try:
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "Hello!"}],
)
except openai.APITimeoutError as e:
print(f"Request timed out: {e.message}")
print(f"Request: {e.request.url}")
Timeout errors are automatically retried by default. See Retries for configuration.
APIStatusError
Base class for all HTTP status code errors (4xx and 5xx responses).
Attributes:
message (str) - Error description
request (httpx.Request) - The request that failed
response (httpx.Response) - The error response
status_code (int) - HTTP status code
request_id (str | None) - Request ID from x-request-id header
body (object | None) - Response body (parsed JSON or raw string)
code (str | None) - Error code from response
param (str | None) - Parameter that caused the error
type (str | None) - Error type from response
import openai
from openai import OpenAI
client = OpenAI()
try:
response = client.chat.completions.create(
model="invalid-model",
messages=[{"role": "user", "content": "Hello!"}],
)
except openai.APIStatusError as e:
print(f"Status code: {e.status_code}")
print(f"Request ID: {e.request_id}")
print(f"Error code: {e.code}")
print(f"Error type: {e.type}")
print(f"Error body: {e.body}")
print(f"Response headers: {e.response.headers}")
BadRequestError (400)
The request was invalid or malformed.
import openai
from openai import OpenAI
client = OpenAI()
try:
response = client.chat.completions.create(
model="gpt-4",
messages=[], # Invalid: empty messages
)
except openai.BadRequestError as e:
print(f"Invalid request: {e.message}")
print(f"Parameter: {e.param}")
AuthenticationError (401)
Authentication failed (invalid API key).
import openai
from openai import OpenAI
client = OpenAI(api_key="invalid-key")
try:
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "Hello!"}],
)
except openai.AuthenticationError as e:
print(f"Authentication failed: {e.message}")
print("Check your API key")
PermissionDeniedError (403)
The API key doesn’t have permission to access the resource.
import openai
from openai import OpenAI
client = OpenAI()
try:
response = client.fine_tuning.jobs.create(
model="gpt-4",
training_file="file-abc123",
)
except openai.PermissionDeniedError as e:
print(f"Permission denied: {e.message}")
print("Check your organization's access level")
NotFoundError (404)
The requested resource doesn’t exist.
import openai
from openai import OpenAI
client = OpenAI()
try:
file = client.files.retrieve("file-nonexistent")
except openai.NotFoundError as e:
print(f"Resource not found: {e.message}")
ConflictError (409)
The request conflicts with the current state of the resource.
import openai
from openai import OpenAI
client = OpenAI()
try:
# Some operation that might conflict
response = client.some_resource.create(...)
except openai.ConflictError as e:
print(f"Conflict: {e.message}")
Conflict errors (409) are automatically retried by default.
UnprocessableEntityError (422)
The request was well-formed but contains semantic errors.
import openai
from openai import OpenAI
client = OpenAI()
try:
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "invalid-role", "content": "Hello!"}],
)
except openai.UnprocessableEntityError as e:
print(f"Validation error: {e.message}")
print(f"Parameter: {e.param}")
RateLimitError (429)
Rate limit exceeded. You’re sending requests too quickly.
import openai
import time
from openai import OpenAI
client = OpenAI()
try:
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "Hello!"}],
)
except openai.RateLimitError as e:
print(f"Rate limit exceeded: {e.message}")
print(f"Request ID: {e.request_id}")
# Check for Retry-After header
retry_after = e.response.headers.get("retry-after")
if retry_after:
print(f"Retry after {retry_after} seconds")
Rate limit errors (429) are automatically retried with exponential backoff. The SDK respects Retry-After headers.
InternalServerError (500+)
The API encountered an internal error.
import openai
from openai import OpenAI
client = OpenAI()
try:
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "Hello!"}],
)
except openai.InternalServerError as e:
print(f"Server error: {e.status_code}")
print(f"Message: {e.message}")
print(f"Request ID: {e.request_id}")
Server errors (5xx) are automatically retried by default.
APIResponseValidationError
Raised when the API response doesn’t match the expected schema.
Attributes:
message (str) - Error description
request (httpx.Request) - The request
response (httpx.Response) - The response
status_code (int) - HTTP status code
body (object | None) - Response body
import openai
from openai import OpenAI
# Enable strict response validation
client = OpenAI(_strict_response_validation=True)
try:
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "Hello!"}],
)
except openai.APIResponseValidationError as e:
print(f"Invalid response: {e.message}")
print(f"Status: {e.status_code}")
print(f"Body: {e.body}")
_strict_response_validation is an internal parameter and may change in future versions.
LengthFinishReasonError
Raised when a completion is truncated due to length limits.
Attributes:
completion (ChatCompletion) - The truncated completion
from openai import OpenAI
from openai.types.chat import ChatCompletion
client = OpenAI()
try:
# Process completion
completion = ChatCompletion(...)
if completion.choices[0].finish_reason == "length":
from openai import LengthFinishReasonError
raise LengthFinishReasonError(completion=completion)
except LengthFinishReasonError as e:
print(f"Response truncated: {e.message}")
if e.completion.usage:
print(f"Tokens used: {e.completion.usage}")
ContentFilterFinishReasonError
Raised when content is filtered due to content policy violations.
from openai import OpenAI
from openai import ContentFilterFinishReasonError
client = OpenAI()
try:
# Process completion
# If finish_reason is "content_filter"
raise ContentFilterFinishReasonError()
except ContentFilterFinishReasonError as e:
print(f"Content filtered: {e}")
InvalidWebhookSignatureError
Raised when webhook signature verification fails.
from openai import OpenAI, InvalidWebhookSignatureError
client = OpenAI()
try:
event = client.webhooks.unwrap(request_body, request_headers)
except InvalidWebhookSignatureError as e:
print(f"Invalid signature: {e}")
# Reject the webhook
Async Error Handling
Error handling works identically with AsyncOpenAI:
import asyncio
import openai
from openai import AsyncOpenAI
client = AsyncOpenAI()
async def main():
try:
response = await client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "Hello!"}],
)
except openai.APIConnectionError as e:
print(f"Connection error: {e}")
except openai.RateLimitError as e:
print(f"Rate limit: {e}")
except openai.APIStatusError as e:
print(f"API error: {e.status_code}")
asyncio.run(main())
Request IDs
All APIStatusError exceptions include a request_id for debugging:
import openai
from openai import OpenAI
client = OpenAI()
try:
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "Hello!"}],
)
except openai.APIStatusError as e:
print(f"Request ID: {e.request_id}")
# Use this ID when contacting support
Retry Strategy
Some errors are automatically retried:
- Connection errors - Network failures
- Timeout errors (408) - Request timeouts
- Conflict errors (409) - Resource conflicts
- Rate limit errors (429) - Too many requests
- Server errors (5xx) - Internal server errors
See Retries for configuration details.
Best Practices
- Always catch specific exceptions before general ones
- Log
request_id for failed requests to help with debugging
- Handle rate limits gracefully with exponential backoff
- Don’t expose API keys in error logs
- Consider retrying transient errors (timeouts, connection errors)
- Check
finish_reason for content filter or length issues