Skip to content

fix(server): return 503 when the proxy connection pool is exhausted - #2519

Open
acodercat wants to merge 1 commit into
opensandbox-group:mainfrom
acodercat:fix/server-proxy-pool-timeout
Open

acodercat wants to merge 1 commit into
opensandbox-group:mainfrom
acodercat:fix/server-proxy-pool-timeout

Conversation

@acodercat

Copy link
Copy Markdown
Contributor

#2084 mapped proxied backend failures to gateway statuses (502 BACKEND_CONNECTION_FAILED, 504 BACKEND_TIMEOUT, 502 BACKEND_RESPONSE_FAILED), so that a sandbox problem no longer looks like a server bug. One timeout was left out: httpx.PoolTimeout.

The proxy shares one httpx.AsyncClient(timeout=180.0), which keeps httpx's default limit of 100 connections. A streamed response (an SSE stream, a long poll, a large download) holds its connection until it finishes. Once all of them are busy, the next proxied request waits 180 seconds for a free connection and then raises PoolTimeout. That isn't caught by any of the backend handlers, so it ends in the generic handler and the client gets 500 GENERAL::UNKNOWN_ERROR, "An internal error occurred in the proxy".

Summary

  • httpx.PoolTimeout now returns 503 with code PROXY_POOL_EXHAUSTED. The server is out of capacity and the sandbox was never contacted, so 503 fits better than 504, and clients can retry.
  • The message names the backend endpoint, like the other proxy errors, and the endpoint headers stay out of it.

Testing

  • Not run (explain why)

  • Unit tests

  • Integration tests

  • e2e / manual verification

  • Added a PoolTimeout case to test_proxy_maps_backend_failure_after_connect_to_gateway_error. It fails on current main with 500.

  • The full server suite passes (2698 passed). ruff and pyright are clean.

Breaking Changes

  • None
  • Yes (describe impact and migration path)

Checklist

  • Linked Issue or clearly described motivation
  • Added/updated docs (if needed)
  • Added/updated tests (if needed)
  • Security impact considered
  • Backward compatibility considered

The shared proxy client keeps httpx's default limit of 100 connections,
and streamed responses hold theirs until they finish. Once all of them
are busy, a new proxied request waits for the client timeout and then
raises httpx.PoolTimeout, which none of the backend failure handlers
catches, so the client got a 500 that looks like a server bug.

Map it to 503 PROXY_POOL_EXHAUSTED: the server is out of capacity, and
the sandbox itself was never reached.
@github-actions github-actions Bot added component/server size/S Denotes a PR that changes 10-29 lines, ignoring generated files. labels Oct 31, 2026
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-31T08:45:03.659137Z 2a5568a PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component/server size/S Denotes a PR that changes 10-29 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant