openai/codex · error · RouteAwareRequestError
redirect target uses unsupported URL scheme: {0}
Error message
redirect target uses unsupported URL scheme: {0} What it means
RouteAwareRequestError::UnsupportedRedirectScheme is raised during the pool's manual redirect following (route_aware_client_pool.rs:635-639). Under RespectSystemProxy (or TLS-backend fallback) reqwest's internal redirects are disabled so each hop gets its own route decision; when a 301/302/303/307/308 Location resolves to a URL whose scheme is not http or https, the pool refuses to follow and returns this error with the offending scheme as its string.
Source
Thrown at codex-rs/http-client/src/route_aware_client_pool.rs:96
/// 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,
#[error("route-aware request timed out")]
Timeout,
}
impl RouteAwareRequestError {
/// Classifies transport, proxy, and certificate failures without exposing request details.
pub fn failure_class(&self) -> Option<RouteFailureClass> {
if self.is_timeout() {
return Some(RouteFailureClass::ConnectTimeout);
}
if self.status() == Some(StatusCode::PROXY_AUTHENTICATION_REQUIRED) {
return Some(RouteFailureClass::ProxyAuthenticationRequired);
}
if let Self::Route(RouteAwareClientPoolError::Resolve(error)) = self
&& let Some(source) = error.get_ref()View on GitHub (pinned to 339751715c)
Solutions
- Trace the redirect chain (curl -IL) and fix the server's Location target to an http/https URL
- If the target scheme is legitimately outside HTTP, handle it at the application layer instead of expecting the pool to follow it
- Use a pool built with RouteAwareClientPool::new_without_redirects so each 3xx response is returned to your code and you decide which hops to follow
- Do not retry: the same Location will fail identically
Example fix
// before
let pool = RouteAwareClientPool::new(factory, ClientRouteClass::Api);
let resp = pool.get(url).send().await?; // UnsupportedRedirectScheme("ftp")
// after: observe redirects yourself and follow only http/https
let pool = RouteAwareClientPool::new_without_redirects(factory, ClientRouteClass::Api);
let resp = pool.get(url).send().await?;
if resp.status().is_redirection() { /* read Location, decide, re-send */ } Defensive patterns
Strategy: try-catch
Type guard
fn is_unsupported_redirect(e: &RouteAwareRequestError) -> bool {
matches!(e, RouteAwareRequestError::UnsupportedRedirectScheme(_))
} Try / catch
Err(RouteAwareRequestError::UnsupportedRedirectScheme(scheme)) => {
// surface the original destination; do not follow non-HTTP schemes
Err(Upstream::RedirectScheme { scheme, from: original_url })
} Prevention
- When URLs (or proxies that rewrite them) are user-configurable, validate the redirect chain's schemes up front
- Prefer a no-redirect pool plus explicit hop handling when redirect targets are untrusted
- Remember RespectSystemProxy pools follow redirects manually: reqwest's default redirect policy does not apply
- Integration-test redirect-heavy flows so scheme changes on the server fail in CI, not production
When it happens
Trigger: Sending through a RouteAwareClientPool that follows redirects manually when the server answers 3xx with Location: ftp://..., file://..., or any non-http(s) URI: the scheme check at route_aware_client_pool.rs:635 fails and the send aborts instead of following the hop.
Common situations: Legacy download endpoints still redirecting to ftp://, misconfigured server or CDN redirect rules, open-redirect probes pointing at exotic schemes, local dev servers redirecting to internal tooling URLs.
Related errors
- remote control URL cannot be a base
- timeout
- network error: {0}
- too many redirects
- route-aware request timed out
AI-assisted analysis of openai/codex@339751715c (2026-08-25).
Data as JSON: /api/errors/e9c0991e61707c4b.
Report an issue: GitHub.