BerriAI/litellm · error · MaskedHTTPStatusError
_text (masked response text)
Error message
_text (masked response text)
What it means
Non-streaming sync path of _raise_masked_sync_error: after an httpx.HTTPStatusError on a sync request, litellm extracts the response text, runs it through mask_sensitive_info (strips API keys/tokens), and raises MaskedHTTPStatusError with that masked text. It preserves the original error via __cause__/context while making the message log-safe.
Source
Thrown at litellm/llms/custom_httpx/http_handler.py:467
def _raise_masked_sync_error(e: httpx.HTTPStatusError, stream: bool) -> None:
"""Raise a MaskedHTTPStatusError for sync HTTP handlers."""
if stream:
try:
_body: Final = mask_sensitive_info(
_safe_read_response(
e.response,
timeout=_STREAMING_ERROR_BODY_READ_TIMEOUT_SECONDS,
)
)
raise MaskedHTTPStatusError(e, message=_body, text=_body) from None
finally:
try:
e.response.close()
except Exception:
pass
_text: Final = mask_sensitive_info(_safe_get_response_text(e.response))
raise MaskedHTTPStatusError(e, message=_text, text=_text) from None
async def _raise_masked_async_error(e: httpx.HTTPStatusError, stream: bool) -> None:
"""Raise a MaskedHTTPStatusError for async HTTP handlers."""
if stream:
try:
_body: Final = mask_sensitive_info(
await _safe_aread_response(
e.response,
timeout=_STREAMING_ERROR_BODY_READ_TIMEOUT_SECONDS,
)
)
raise MaskedHTTPStatusError(e, message=_body, text=_body) from None
finally:
try:
await e.response.aclose()
except Exception:
passView on GitHub (pinned to 6c2dcb801b)
Solutions
- Handle httpx.HTTPStatusError / MaskedHTTPStatusError at the call site and branch on status code
- Address the upstream cause: credentials, model names, payloads, quotas
- Log the masked message safely; do not disable masking in shared log sinks
Example fix
# before
result = litellm.completion(model=..., messages=...) # surfaces MaskedHTTPStatusError
# after
import httpx
try:
result = litellm.completion(model=..., messages=...)
except httpx.HTTPStatusError as e:
logging.warning("upstream %s: %s", e.response.status_code, str(e)[:200])
raise Defensive patterns
Strategy: try-catch
Try / catch
import httpx
try:
result = litellm.completion(...)
except httpx.HTTPStatusError as e: # MaskedHTTPStatusError subclasses this
handle_by_status(e.response.status_code) Prevention
- Catch httpx.HTTPStatusError once at the service boundary and normalize to your app's error type
- Rely on litellm's masking instead of logging raw URLs/bodies yourself
When it happens
Trigger: Any sync HTTPHandler request (completion, embedding, etc.) that returns an HTTP error status — the raise_for_status() failure routes here and the upstream body becomes the exception message.
Common situations: Bad API keys where the provider echoes the key in the error; misrouted api_base producing provider error bodies; quota/billing errors. The masking exists so logged exceptions do not leak credentials.
Related errors
- _body (masked response body)
- Failed to transform Braintrust response: {str(e)}
- Error apply_db_fixes: {str(e)}
- Error getting prompt from Humanloop: {e.response.text}
- error_msg (upstream response error message)
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/8427517186635253.
Report an issue: GitHub.