{"record":{"id":"cb8452d5ee1e03fb","repo":"openai/codex","slug":"unknown-network-proxy-attribution-token","errorCode":null,"errorMessage":"unknown network proxy attribution token","messagePattern":"unknown network proxy attribution token","errorType":"exception","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"codex-rs/network-proxy/src/attribution.rs","lineNumber":51,"sourceCode":"            inner,\n            state,\n            environment_id,\n        }\n    }\n}\n\nimpl<S> Service<TcpStream> for BindConnectionAttribution<S>\nwhere\n    S: Service<TcpStream>,\n    S::Error: Into<BoxError>,\n{\n    type Output = S::Output;\n    type Error = BoxError;\n\n    async fn serve(&self, mut stream: TcpStream) -> Result<Self::Output, Self::Error> {\n        let state = match read_attribution_token(&mut stream).await? {\n            Some(token) => self.state.for_execution_token(&token).ok_or_else(|| {\n                io::Error::new(\n                    io::ErrorKind::PermissionDenied,\n                    \"unknown network proxy attribution token\",\n                )\n            })?,\n            None => self.state.as_ref().clone(),\n        };\n        if let Some(expected_environment_id) = self.environment_id.as_deref()\n            && state\n                .environment_id()\n                .is_some_and(|actual| actual != expected_environment_id)\n        {\n            return Err(io::Error::new(\n                io::ErrorKind::PermissionDenied,\n                \"network proxy attribution environment mismatch\",\n            )\n            .into());\n        }\n        stream.extensions_mut().insert(Arc::new(state));","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/openai/codex/blob/339751715c64496cb86246bfb3935f40e309dd3d/codex-rs/network-proxy/src/attribution.rs#L33-L69","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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.","Restart the execution/bridge so a fresh token is minted and registered with the proxy state.","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."],"exampleFix":"// before: token read once at startup and reused across proxy restarts\nstatic TOKEN: OnceLock<String> = OnceLock::new(); // goes stale\n// after: read per connection attempt so a restart mints a new value\nlet token = std::env::var(\"CODEX_NETWORK_PROXY_ATTRIBUTION\")\n    .map_err(|e| io::Error::new(io::ErrorKind::NotFound, format!(\"attribution token missing: {e}\")))?;","handlingStrategy":"try-catch","validationCode":"// Rust: fail fast with a clear message before connecting\nlet token = std::env::var(\"CODEX_NETWORK_PROXY_ATTRIBUTION\").map_err(|e| {\n    io::Error::new(io::ErrorKind::NotFound, format!(\"attribution token missing: {e}\"))\n})?;\nif token.is_empty() || token.len() > 128 {\n    return Err(io::Error::new(io::ErrorKind::InvalidInput, \"attribution token must be 1..=128 bytes\"));\n}","typeGuard":null,"tryCatchPattern":"// After connect + write_attribution_frame, classify the ingress rejection:\nif let Some(e) = err.downcast_ref::<io::Error>() {\n    if e.kind() == io::ErrorKind::PermissionDenied\n        && e.to_string().contains(\"unknown network proxy attribution token\")\n    {\n        // token is stale: re-read CODEX_NETWORK_PROXY_ATTRIBUTION and reconnect once\n    }\n}","preventionTips":["Never persist or cache attribution tokens; they are scoped to one execution/proxy lifetime.","Re-read CODEX_NETWORK_PROXY_ATTRIBUTION on every reconnect attempt.","Treat a proxy restart as invalidating all outstanding tokens."],"tags":["rust","codex","network-proxy","attribution","permission-denied"],"backgroundTag":"invalid-auth-token","analyzedSha":"339751715c64496cb86246bfb3935f40e309dd3d","analyzedAt":"2026-08-25T05:35:09.876Z","schemaVersion":2},"datasetVersion":"2026-08-25T06:17:31.827Z"}