`codex exec-server --remote` registration omits `User-Agent` header

Open 💬 1 comment Opened May 23, 2026 by imryao

Summary

When codex exec-server runs in --remote mode, the two outbound calls to the environment registry / rendezvous travel without a User-Agent header:

  1. POST {base_url}/cloud/environment/{environment_id}/register — uses reqwest::Client::new() (codex-rs/exec-server/src/remote.rs:41 on rust-v0.133.0), which does not set a default UA.
  2. connect_async(rendezvous_url) — uses tokio-tungstenite's default handshake, which does not set one either.

This is the only outbound path in codex that omits the UA. Every other outbound HTTP call already routes through codex_login::default_client::get_codex_user_agent() — see codex-rs/backend-client/src/client.rs:174 (ClientBuilder::user_agent(...)) and codex-rs/app-server/src/request_processors/initialize_processor.rs:140 (process-global UA suffix set during initialize).

Why it matters

For server-side observability — release-health stats, version-distribution telemetry, debugging connection issues — the upstream registry can't tell which codex version / OS / architecture is connecting from headers alone. The only identifying signal is whatever the auth token's claims carry.

Proposal

Mirror backend-client's pattern in exec-server:

  • Replace reqwest::Client::new() with reqwest::Client::builder().user_agent(get_codex_user_agent()).build().
  • Wrap the rendezvous URL in an http::Request with a User-Agent header and pass that to connect_async.

No protocol changes, no server-side change required (unknown headers are ignored). Resulting UA shape matches what backend-client already sends:

codex_cli_rs/<ver> (<os> <os_ver>; <arch>) tungstenite-rs/<ver>

Happy to send a PR — branch is ready locally if there's interest. Wanted to surface as an issue first to confirm the team would accept this kind of change before opening one.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗