Skip to content

HTTP 499 CANCELLED should be in the default retryable status codes #2506

@MarwanMashra

Description

@MarwanMashra

Summary

_RETRY_HTTP_STATUS_CODES in _api_client.py does not include HTTP 499. When Gemini returns 499 CANCELLED, the SDK raises ClientError immediately without retrying, even when HttpRetryOptions(attempts=N) is configured.

Current behavior

_RETRY_HTTP_STATUS_CODES = (
    408,  # Request timeout.
    429,  # Too many requests.
    500,  # Internal server error.
    502,  # Bad gateway.
    503,  # Service unavailable.
    504,  # Gateway timeout
)

A 499 CANCELLED response from Gemini is a ClientError with code=499. The retry predicate in retry_args() checks e.code in retriable_codes, finds no match, and raises immediately.

Expected behavior

499 should be retried like other transient server errors. HTTP 499 from Google's API indicates the server cancelled the operation — not the client. It is transient and succeeds on retry.

Evidence

We observed this in production: three Gemini API calls (gemini-3.1-pro-preview) failed with 499 CANCELLED in a one-hour window. All three were fast failures (~8 seconds, not timeouts). Subsequent identical calls in the same pipeline succeeded. The max_retries=3 configuration had no effect because 499 is not in the retryable set.

The same issue was reported in google/adk-python#475, where the ADK team added HttpRetryOptions support but did not update the default retryable codes in this SDK.

Suggested fix

Add 499 to _RETRY_HTTP_STATUS_CODES:

_RETRY_HTTP_STATUS_CODES = (
    408,  # Request timeout.
    429,  # Too many requests.
    499,  # Client closed request / server cancelled.
    500,  # Internal server error.
    502,  # Bad gateway.
    503,  # Service unavailable.
    504,  # Gateway timeout
)

Workaround

Users can pass http_status_codes explicitly via HttpRetryOptions, but this is not exposed by higher-level integrations like langchain-google-genai, which only sets attempts.

Environment

  • google-genai: 1.75.0 (also verified on main / v2.6.0 — same behavior)
  • Python: 3.12
  • Observed on: Gemini gemini-3.1-pro-preview via the Gemini Developer API

Metadata

Metadata

Labels

priority: p2Moderately-important priority. Fix may not be included in next release.status:awaiting user responsetype: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions