openai/codex · error · io::Error

unknown network proxy attribution token

Error message

unknown network proxy attribution token

What it means

The network-proxy ingress read a structurally valid bridge preface, but the attribution token in it does not resolve to any registered execution: NetworkProxyState::for_execution_token() returned None. Tokens are minted per sandboxed execution and handed over via the CODEX_NETWORK_PROXY_ATTRIBUTION env var, so 'unknown' means the token is stale, evicted (its execution ended or the proxy restarted), or never belonged to this proxy. The connection is rejected with io::ErrorKind::PermissionDenied before any proxied traffic flows.

Source

Thrown at codex-rs/network-proxy/src/attribution.rs:51

            inner,
            state,
            environment_id,
        }
    }
}

impl<S> Service<TcpStream> for BindConnectionAttribution<S>
where
    S: Service<TcpStream>,
    S::Error: Into<BoxError>,
{
    type Output = S::Output;
    type Error = BoxError;

    async fn serve(&self, mut stream: TcpStream) -> Result<Self::Output, Self::Error> {
        let state = match read_attribution_token(&mut stream).await? {
            Some(token) => self.state.for_execution_token(&token).ok_or_else(|| {
                io::Error::new(
                    io::ErrorKind::PermissionDenied,
                    "unknown network proxy attribution token",
                )
            })?,
            None => self.state.as_ref().clone(),
        };
        if let Some(expected_environment_id) = self.environment_id.as_deref()
            && state
                .environment_id()
                .is_some_and(|actual| actual != expected_environment_id)
        {
            return Err(io::Error::new(
                io::ErrorKind::PermissionDenied,
                "network proxy attribution environment mismatch",
            )
            .into());
        }
        stream.extensions_mut().insert(Arc::new(state));

View on GitHub (pinned to 339751715c)

Solutions

  1. Re-read the token from the live execution's CODEX_NETWORK_PROXY_ATTRIBUTION env var and reconnect -- tokens are scoped to the current proxy lifetime.
  2. Restart the execution/bridge so a fresh token is minted and registered with the proxy state.
  3. If it persists, verify the bridge connects to the ingress of the codex session that spawned it, not a leftover port from an earlier run.

Example fix

// before: token read once at startup and reused across proxy restarts
static TOKEN: OnceLock<String> = OnceLock::new(); // goes stale
// after: read per connection attempt so a restart mints a new value
let token = std::env::var("CODEX_NETWORK_PROXY_ATTRIBUTION")
    .map_err(|e| io::Error::new(io::ErrorKind::NotFound, format!("attribution token missing: {e}")))?;
Defensive patterns

Strategy: try-catch

Validate before calling

// Rust: fail fast with a clear message before connecting
let token = std::env::var("CODEX_NETWORK_PROXY_ATTRIBUTION").map_err(|e| {
    io::Error::new(io::ErrorKind::NotFound, format!("attribution token missing: {e}"))
})?;
if token.is_empty() || token.len() > 128 {
    return Err(io::Error::new(io::ErrorKind::InvalidInput, "attribution token must be 1..=128 bytes"));
}

Try / catch

// After connect + write_attribution_frame, classify the ingress rejection:
if let Some(e) = err.downcast_ref::<io::Error>() {
    if e.kind() == io::ErrorKind::PermissionDenied
        && e.to_string().contains("unknown network proxy attribution token")
    {
        // token is stale: re-read CODEX_NETWORK_PROXY_ATTRIBUTION and reconnect once
    }
}

Prevention

When it happens

Trigger: A bridge client sends the magic frame plus a token that was never registered with this NetworkProxyState -- e.g. reusing a CODEX_NETWORK_PROXY_ATTRIBUTION value captured before a proxy restart, or a hand-written token in a custom test client.

Common situations: Proxy process restarted while a long-lived bridge kept the old token; the env var copied from a previous session into a new shell or CI job; a bridge connecting to a stale proxy port left over from another codex run.

Related errors


AI-assisted analysis of openai/codex@339751715c (2026-08-25). Data as JSON: /api/errors/cb8452d5ee1e03fb. Report an issue: GitHub.