Skip to content

Transport: httpx network errors (ConnectError/NetworkError/etc.) never retry, even for GET/HEAD/OPTIONS #240

Closed

Description

@TexasCoding

Summary

Transient ECONNRESET, DNS hiccups, HTTP/2 RST_STREAM, server half-closes, and TCP connect refusals on a safe idempotent GET (markets list, portfolio snapshot, etc.) surface as a one-shot failure to the caller. The retry loop only handles TimeoutException and PoolTimeout; every other httpx.HTTPError subclass lands in a final except and re-raises with no retry.

Industry-standard SDKs (openai-python, anthropic-python, stripe-python, urllib3) all retry idempotent verbs on transport-level errors. ConnectError on POST is in principle also safe to retry (request never reached the wire, mirroring the PoolTimeout reasoning from #204).

Location

  • kalshi/_base_client.py:284-286 — sync transport final except httpx.HTTPError
  • kalshi/_base_client.py:466-467 — async transport mirror

Evidence

except httpx.HTTPError as e:
    raise KalshiError(f"HTTP error: {method.upper()} {path}") from e

# httpx hierarchy: ConnectError/NetworkError/RemoteProtocolError/ReadError/WriteError
# all inherit from TransportError -> RequestError -> HTTPError.

Recommended fix

Insert an except httpx.TransportError (or split out ConnectError/NetworkError/RemoteProtocolError/ReadError/WriteError) between TimeoutException and HTTPError that participates in the same RETRYABLE_METHODS + backoff + total_timeout budget loop. Mirror the PoolTimeout "never reached the wire" branch for ConnectError so POST/DELETE can retry only on pre-wire failures.

Severity & category

high / reliability

Activity

  1. added 2 commits that reference this issue on May 21, 2026
    fc9d6f6
    d372af1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions