Skip to main content

Error Handling

The Zscaler SDK provides a comprehensive exception hierarchy for handling errors.

The SDK normalizes error handling across all services (Authentication Service, Client Connector, Cloud & Branch Connector, ZDX, ZIA, and ZPA), so you work with the same exception classes irrespective of which service raised them. At the same time, it preserves service-specific error details on each exception instance, including HTTP status code, request ID, error message, and resource or action context.

HTTP status codes and service-specific error codes

For a full list of HTTP status codes that OneAPI returns and the service-specific error codes that each product might return, see Understanding Response Codes & Error Messages. You can also access individual product pages (Authentication Service, Business Insights, Client Connector, Cloud & Branch Connector, ZDX, ZIA, and ZPA) from there.

Exception Hierarchy

OneApiError (base)
├── ZsResourceError (resource layer)
│ ├── BadRequestException (400)
│ ├── AuthenticationException (401)
│ ├── AuthenticationException (403)
│ ├── NotFoundException (404)
│ ├── RequestTimeoutException (408)
│ ├── ConflictException (409)
│ ├── GoneException (410)
│ ├── PreconditionFailedException (412)
│ ├── PreconditionRequiredException (428)
│ ├── ThrottledException (429)
│ └── ParamValidationError (client-side validation)

Basic Error Handling

import zssdk
from zssdk.zscore.config import Config, LoggerConfig
from zssdk.zscore import OneApiError
from zssdk.zsresource import ZsResourceError
from zssdk.zsresource.exceptions import (
BadRequestException,
NotFoundException,
AuthenticationException,
ThrottledException,
)

# Enable debug logging for troubleshooting
logger_config = LoggerConfig(
enabled=True,
verbose=True,
log_to_file=True,
log_file_path="error_handling.log",
)

config = Config(logger_config=logger_config)

session = zssdk.Session(
vanity_domain="your-vanity-domain",
client_id="your-client-id",
client_secret="your-client-secret",
config=config
)

try:
role = session.zia.AdminRole(id=99999)
role.load()
except NotFoundException as e:
print(f"Role not found: {e}")
except BadRequestException as e:
print(f"Invalid request: {e}")
print(f"Status code: {e.status_code}")
except AuthenticationException as e:
print(f"Authentication failed: {e}")
except ThrottledException as e:
print(f"Rate limited (status {e.status_code}): {e}")
except ZsResourceError as e:
print(f"Resource error: {e}")
except OneApiError as e:
print(f"SDK error: {e}")

Exception Attributes

All exceptions include the following useful attributes:

try:
role = session.zia.AdminRole(id=99999)
role.load()
except ZsResourceError as e:
print(f"Error type: {type(e).__name__}")
print(f"Message: {e}")
print(f"Status code: {e.status_code}")
print(f"Resource: {e.resource_name}")
print(f"Action: {e.action_name}")
print(f"Request ID: {e.request_id}")

Common Error Scenarios

400 Bad Request​

Invalid parameters or malformed request:

try:
role = session.zia.AdminRole()
role.name = "" # Empty name is invalid
role.create()
except BadRequestException as e:
print(f"Validation error: {e}")
# Debug logging shows the exact request that failed

401 or 403 Authentication Error​

Invalid or expired credentials:

try:
session = zssdk.Session(
vanity_domain="your-vanity-domain",
client_id="invalid",
client_secret="invalid",
)
list(session.zia.admin_roles)
except AuthenticationException as e:
print(f"Check your credentials: {e}")
print(f"Status code: {e.status_code}")

404 Not Found​

Resource doesn't exist:

try:
role = session.zia.AdminRole(id=99999)
role.load()
except NotFoundException as e:
print(f"Role ID 99999 not found")
print(f"Resource: {e.resource_name}")

409 Conflict​

Resource already exists or is in a conflicting state:

try:
# Try to create duplicate resource
role = session.zia.AdminRole()
role.name = "Existing Role"
role.create()
except ConflictException as e:
print(f"Resource conflict: {e}")
print(f"Consider using update() instead of create()")

429 Rate Limit​

Too many requests:

from zssdk.zsresource.exceptions import ThrottledException

try:
# The SDK transparently retries on 429 with exponential backoff
# before raising. By the time you catch ThrottledException here,
# automatic retries have already been exhausted — typically you
# want to back off in the application (slow the caller, push to a
# dead-letter queue, etc.) rather than retry again immediately.
for i in range(1000):
list(session.zia.admin_roles)
except ThrottledException as e:
print(f"Still rate limited after SDK retries: {e}")
print(f"Status code: {e.status_code}")

500+ Server Errors​

Server-side issues:

from zssdk.zscore import OneApiError

try:
# Server-side failures (5xx) surface as the generic OneApiError —
# there is no dedicated ServerException class. The SDK's transport
# layer already retries transient 5xx responses (with exponential
# backoff, capped at 300 s, up to max_attempts) before raising,
# so by the time you catch this exception automatic retries are
# exhausted and you should fall back to application-level handling.
role = session.zia.AdminRole(id="your-role-id")
role.load()
except OneApiError as e:
print(f"Server error: {e}")
print(f"Status code: {e.status_code}")

Debugging with Logs

Enable comprehensive logging to troubleshoot errors:

import zssdk
from zssdk.zscore.config import Config, LoggerConfig

# Configure detailed logging using SDK's LoggerConfig
logger_config = LoggerConfig(
enabled=True,
verbose=True,
log_to_file=True,
log_file_path="debug_errors.log",
)

config = Config(logger_config=logger_config)

# Session with comprehensive logging enabled
session = zssdk.Session(
vanity_domain="your-vanity-domain",
client_id="your-client-id",
client_secret="your-client-secret",
config=config
)

# Debug output shows:
# - HTTP request details (URL, headers, body)
# - HTTP response details (status, headers, body)
# - Token refresh attempts
# - Resource processing steps
# - Error parsing and exception creation

Related

  • Understanding Response Codes & Error Messages: Complete reference for HTTP status codes and service-specific error codes (Authentication Service, Business Insights, Client Connector, Cloud & Branch Connector, ZDX, ZIA, and ZPA)
  • Rate Limiting guide: Explains how ThrottledException (429) is handled and retried automatically
  • Logging guide: Shows how to enable verbose logging to inspect the exact request and response that triggered an exception