openai/codex · error · RouteAwareClientPoolError
failed to resolve the outbound proxy route: {0}
Error message
failed to resolve the outbound proxy route: {0} What it means
RouteAwareClientPoolError::Resolve is produced in client_for_url_with_resolver (route_aware_client_pool.rs:723-725) when the async route resolver returns an io::Error. The resolver is HttpClientFactory::resolve_proxy_route_async (outbound_proxy.rs:242-276): on Windows/macOS the platform lookup runs under spawn_blocking, so the io::Error typically comes from the semaphore acquire or the blocking task failing to join (runtime shutdown, task panic); the synchronous resolution itself falls back to env/direct instead of erroring. failure_class() maps it to ProxyResolutionUnavailable (or TlsError when the io::Error carries a rustls error).
Source
Thrown at codex-rs/http-client/src/route_aware_client_pool.rs:81
custom_ca_fallback: CustomCaFallback,
clients: Arc<Mutex<HashMap<OutboundProxyRoute, HttpClient>>>,
rustls_clients: Option<RustlsClientCache>,
}
impl fmt::Debug for RouteAwareClientPool {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter
.debug_struct("RouteAwareClientPool")
.field("http_client_factory", &self.http_client_factory)
.field("route_class", &self.route_class)
.finish_non_exhaustive()
}
}
/// Error returned when selecting a route or constructing its pooled HTTP client.
#[derive(Debug, thiserror::Error)]
pub enum RouteAwareClientPoolError {
#[error("failed to resolve the outbound proxy route: {0}")]
Resolve(#[source] io::Error),
#[error(transparent)]
Build(#[from] BuildRouteAwareHttpClientError),
}
/// Error returned while building, routing, or sending a route-aware request.
#[derive(Debug, thiserror::Error)]
pub enum RouteAwareRequestError {
#[error(transparent)]
Request(#[from] reqwest::Error),
#[error(transparent)]
Route(#[from] RouteAwareClientPoolError),
#[error("failed to build route-aware request: {0}")]
Build(String),
#[error("redirect target uses unsupported URL scheme: {0}")]
UnsupportedRedirectScheme(String),
#[error("too many redirects")]
TooManyRedirects,View on GitHub (pinned to 339751715c)
Solutions
- Check whether the runtime is being shut down or the send future was cancelled while platform proxy resolution was in flight; drain in-flight requests before shutdown
- Retry the send: successful resolutions are cached (60s TTL) so a retry usually hits the cache or completes the lookup
- Update codex-rs if the platform binding panic is a known issue, and capture the io::Error's source for the report
- As a workaround, run with OutboundProxyPolicy::ReqwestDefault or env-only proxies to skip platform resolution entirely
Example fix
// before
let resp = pool.get(url).send().await?; // Resolve(io::Error) aborts the caller
// after: retry once, then fall back to a direct-route factory
let resp = match pool.get(url.clone()).send().await {
Err(RouteAwareRequestError::Route(RouteAwareClientPoolError::Resolve(_))) =>
pool.get(url).send().await?,
other => other?,
}; Defensive patterns
Strategy: fallback
Type guard
fn is_route_resolve_error(e: &RouteAwareRequestError) -> bool {
matches!(e, RouteAwareRequestError::Route(RouteAwareClientPoolError::Resolve(_)))
} Try / catch
match error {
RouteAwareRequestError::Route(RouteAwareClientPoolError::Resolve(io)) => {
tracing::warn!(source = %io, "proxy route resolution unavailable");
// resolution results are cached; one retry is cheap, then degrade
retry_once_or_direct(factory).await
}
_ => return Err(error),
} Prevention
- Do not abort in-flight sends during runtime shutdown; drain them first
- Treat failure_class() == ProxyResolutionUnavailable as 'retry once, then degrade' rather than fatal
- Monitor resolver failures separately from TLS and timeout classes
- In tests, keep the runtime alive until spawned sends resolve to avoid join failures
When it happens
Trigger: Sending via RouteAwareClientPool with RespectSystemProxy on Windows/macOS while the spawn_blocking PAC/WinHTTP/system-proxy lookup fails to join: the tokio runtime is shutting down, the request future is cancelled mid-lookup, or the platform binding panics. It propagates to callers as RouteAwareRequestError::Route(RouteAwareClientPoolError::Resolve(..)).
Common situations: Dropping request futures during graceful-shutdown drains in servers, test harnesses tearing down the runtime while sends are in flight, bugs in platform proxy bindings after an upgrade.
Related errors
- Failed to configure outbound proxy selected for {route_class
- upstream URL must include a host
- Unsupported platform: ${platform} (${arch})
- Unsupported target triple: ${targetTriple}
- Missing optional dependency ${platformPackage}. Reinstall Co
AI-assisted analysis of openai/codex@339751715c (2026-08-25).
Data as JSON: /api/errors/953460b6f3618e3a.
Report an issue: GitHub.