openai/codex · error · anyhow::Error
creating HTTP server: {err}
Error message
creating HTTP server: {err} What it means
After bind_listener succeeds, run_main wraps the listener with Server::from_listener. If constructing the server from the listener fails (socket option setup, internal task spawn), the error is wrapped as 'creating HTTP server: {err}' with the underlying cause carried in the message suffix.
Source
Thrown at codex-rs/responses-api-proxy/src/lib.rs:101
HeaderValue::from_str(&host).context("constructing Host header from upstream URL")?;
let forward_config = Arc::new(ForwardConfig {
upstream_url,
host_header,
});
let dump_dir = args
.dump_dir
.map(ExchangeDumper::new)
.transpose()
.context("creating --dump-dir")?
.map(Arc::new);
let (listener, bound_addr) = bind_listener(args.port)?;
if let Some(path) = args.server_info.as_ref() {
write_server_info(path, bound_addr.port())?;
}
let server = Server::from_listener(listener, None)
.map_err(|err| anyhow!("creating HTTP server: {err}"))?;
let client = Arc::new(
Client::builder()
// Disable reqwest's 30s default so long-lived response streams keep flowing.
.timeout(None::<Duration>)
.build()
.context("building reqwest client")?,
);
eprintln!("responses-api-proxy listening on {bound_addr}");
let http_shutdown = args.http_shutdown;
for request in server.incoming_requests() {
let client = client.clone();
let forward_config = forward_config.clone();
let dump_dir = dump_dir.clone();
std::thread::spawn(move || {
if http_shutdown && request.method() == &Method::Get && request.url() == "/shutdown" {
let _ = request.respond(Response::new_empty(StatusCode(200)));View on GitHub (pinned to 339751715c)
Solutions
- Read the text after 'creating HTTP server:' - it contains the real io/runtime error
- Check and raise file-descriptor limits (ulimit -n) if the process is near exhaustion
- Restart the proxy; transient setup failures usually clear on retry
- If reproducible, capture full stderr and report upstream with the wrapped cause
Defensive patterns
Strategy: try-catch
Try / catch
match run_main(args).await {
Ok(()) => {}
Err(e) if e.to_string().starts_with("creating HTTP server") => {
eprintln!("proxy failed to initialize server: {e:#}");
std::process::exit(1);
}
Err(e) => { eprintln!("proxy error: {e:#}"); std::process::exit(1); }
} Prevention
- Run the proxy with generous file-descriptor limits
- Supervise with restart-on-failure and backoff
- Distinguish from 'failed to bind' - bind failures need a port change; from_listener failures usually need an environment fix
When it happens
Trigger: Server::from_listener returning Err right after a successful bind - for example failure configuring the accepted socket, a runtime/task spawn failure, or a listener handle in an invalid state.
Common situations: File-descriptor exhaustion (EMFILE) around accept-loop setup; restricted sandboxes blocking socket option calls; rare fork/exec edge cases. The common startup failure 'failed to bind {addr}' happens earlier and is a different error.
Related errors
- server stopped unexpectedly
- {message}
- {context}: {source}
- InvalidInput
- Unsupported platform: ${platform} (${arch})
AI-assisted analysis of openai/codex@339751715c (2026-08-25).
Data as JSON: /api/errors/c184c8de837fc7af.
Report an issue: GitHub.