You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Windows Browser Use fails before reading attached Chrome tab: "Unable to load browser request-header policy" #44112
I’m experiencing the same failure on my Windows machine after updating Codex. Browser control worked normally before I updated; afterward, both Chrome and Edge stopped working through Codex. This blocks all browser automation workflows I have tested.
My versions
Codex desktop: 26.903.8094.0 (Windows x64)
Bundled browser component: 26.903.61454
Chrome ChatGPT extension: 1.26.901.11451, enabled, with no visible extension error
I did not record the previous working desktop version.
Reproduction and impact
When I ask Codex to inspect browser state, cua.getState() repeatedly fails after approximately 20–21 seconds with:
Unable to load browser request-header policy. Retry the browser command.
I also tested Edge with the profile containing the ChatGPT extension. An explicit cua.createBrowserTab('edge', 'https://example.com', ...) fails with the same error. Fully restarting Codex and resetting the CUA JavaScript session did not help. This completely blocks browser control on my machine, rather than affecting just one website.
Diagnostic findings from troubleshooting with Codex
My desktop logs report the extension installed and the bundled Chrome plugin current.
The bundled browser-service.mjs throws this exact error when Statsig initialization is unsuccessful or the client is not Ready, before obtaining the codex_browser_use_agent_request_header gate.
My desktop logs also record Timed out while fetching post-login Statsig bootstrap. This is related evidence, not proof that the desktop bootstrap and browser runtime request have the same underlying failure.
An independent valid initialization POST to https://ab.chatgpt.com/v1/initialize from the bundled Node runtime on my machine returned HTTP 200 and a complete response in approximately 3.2 seconds. This test used a synthetic diagnostic identity. It rules out complete endpoint unreachability at that moment, but does not establish that the browser tool’s own request path is working.
I can confirm that browser control worked before the update and failed afterward. I’m reporting this as an update regression; I don’t yet know the exact underlying request exception or which change caused it. Please investigate this shared mandatory initialization path and expose the underlying failure in diagnostics. I have not included credentials, cookies, private page content, or raw account logs.
I am seeing the same request-header-policy failure using Chrome from the ChatGPT desktop app on Windows.
The extension is installed and enabled. Chrome is detected, but the browser-control task reports that it cannot load its request-header policy before opening a harmless public test page. The task reports that no webpage was changed.
The failure persists in a fresh Work chat and after fully quitting and reopening the desktop app. No cause has been established, and I am not attributing it to a particular release or network setting.
In-app feedback was successfully submitted. Feedback ID: 01a08701-e4b3-7ea2-985d-598f41be3c21.
Exact desktop-app, Chrome and extension versions have not yet been verified for this report. Please advise whether these diagnostics identify a known issue, a specific affected/fixed version, or a supported next diagnostic step. No account credentials, cookies, tokens, private page content or project information are included here.
Adding a macOS reproduction of the same error from a user-authorized diagnostic session on September 11, 2026 (Asia/Shanghai).
Environment:
macOS 26.5.2
Desktop application bundle: ChatGPT.app, version 26.903.61454 (8378)
Google Chrome 152.0.7977.83
Reproduction:
Chrome is running with the ChatGPT extension enabled in its Default profile. The native-host manifest and running host process are present.
Request browser state or call cua.listTabs({browser: 'chrome'}).
The command fails with Unable to load browser request-header policy. Retry the browser command. A measured listTabs attempt took approximately 20.06 seconds.
Opening a separate Chrome window on about:blank through native UI control and retrying once produces the same error. This reproduces independently of the original website. Earlier Chrome restarts and reconnections did not restore the extension channel.
Read-only findings in the bundled browser-service.mjs:
On the affected policy-read path, ef.sendSessionRequest reads the request-header policy before dispatching the session request through sendRequest. This is conditional: getInfo is excluded and an already-enabled header setting can short-circuit the policy read.
The exact error is thrown by mk when the current ready result is unsuccessful or client.loadingStatus !== 'Ready'. That readiness state can be replaced by a user update. A missing/unrecognized feature gate has a different error, so we have not established a missing gate as the cause.
Cached and app-bundled copies of this file match. This does not look like a stale cached copy differing from the installed bundle.
Desktop logs also contain Timed out while fetching post-login Statsig bootstrap and a failed /wham/statsig/bootstrap fetch. These are correlated symptoms, not proof that the desktop bootstrap and browser SDK request share the same underlying failure.
Repeated ordinary commands did not recover in this session. However, the code contains an updateUserAsync reinitialization path, so we are not claiming that all retries permanently reuse one failed initialization. The browser SDK's underlying HTTP/exception details remain unknown; these observations do not distinguish a client recovery defect, a service response problem, or a request-specific network failure.
Native Chrome control did work during the same session, although it also showed a separate intermittent window/accessibility issue. We have not established that the two symptoms share a cause.
Please expose the underlying configuration-initialization failure and advise a supported recovery or fixed version. No request-header gate, browser security setting, or user profile data was modified. No credentials, cookies, private page content, raw logs, or account/session identifiers are included in this report.
Also reproducible on macOS with Codex desktop version 26.903.71938.
The built-in Chrome browser API consistently fails before page interaction:
cua.getState() returns an empty browser list plus the policy error after approximately 20 seconds.
cua.createBrowserTab("chrome", "https://www.xiaohongshu.com/explore", { sessionName: "Connection test" }) fails with the same error after approximately 20 seconds.
Unable to load browser request-header policy. Retry the browser command.
Updating and restarting Codex, and reinstalling the Chrome extension, did not resolve it. Local extension/native-host diagnostics previously reported the extension enabled and the native messaging host correctly configured.
As a comparison, Chrome DevTools MCP with --autoConnect works on the same machine and existing Chrome profile: it can list tabs, open a page, and read page content. A persistent MCP session also successfully handled successive calls. This is a working alternative connection path, not a fix for the built-in browser integration.
In-app feedback has been submitted. Feedback ID: 01a08e9c-c155-75b3-bc67-8e22d0d7fe93.
+1, reproduced on macOS — confirming keamm1x-sys's reproduction in #44112 with an additional data point (the network path to all Statsig backends is verifiably healthy from the affected machine), plus a working local workaround.
Working local workaround (verified)
Following the short-circuit path keamm1x-sys pointed out in #44112, I found a complete local fix: the extension-side "already enabled" state is just a sticky flag in the extension's own chrome.storage.local:
And on the desktop side (browser-service.mjs, sendSessionRequest), the Statsig policy read is skipped entirely when the extension's getInfo reports agentRequestHeaderEnabled === true:
leti=this.requestHeaderEnabled||this.clientInfo.agentRequestHeaderEnabled===true||awaitthis.readRequestHeaderEnabled();// ← skipped via || short-circuit
So pre-seeding the flag does exactly what a successful policy read would have done:
Open chrome://extensions, enable Developer mode;
On the ChatGPT extension card, click Service Worker;
Retry the browser command in Codex (restart the app once if it still fails, so it re-fetches getInfo).
Verified working on my machine: Chrome control is fully restored after setting the flag. The flag persists across Chrome restarts (it lives in chrome.storage.local). Rollback: chrome.storage.local.remove('AGENT_REQUEST_HEADER_ENABLED').
This also explains why many users never hit the bug: anyone whose extension already holds the sticky flag (from a previously successful policy read) permanently short-circuits the Statsig path. Only users whose flag was never written (fresh extension install, cleared storage, or first use after the regression shipped) hit the failing policy read.
Note on intent: the flag only asserts the agent request header locally; for accounts where the codex_browser_use_agent_request_header gate resolves to true anyway, this restores intended behavior rather than bypassing a restriction. A more robust official fix would be for the desktop side to tolerate policy-load failure (fail open with a cached/last-known decision, or surface a real permission prompt) instead of hard-failing every browser command.
However, every endpoint involved in this path is reachable and fast from the same machine at the same time (plain curl, no SDK key, so 403 is expected — the point is TCP/TLS/HTTP all complete in under a second):
Endpoint
Result
https://api.oaistatsig.com/v1/initialize
HTTP 403 in 0.67 s
https://statsigcdn.openai.com/v1
HTTP 403 in 0.37 s
https://ab.chatgpt.com/v1
HTTP 403 in 0.30 s
https://chatgpt.com/backend-api/aura/identity
HTTP 403 in <1 s
So the renderer's post-login Statsig bootstrap times out while the network path to all three Statsig backends is healthy — consistent with the original reporter's finding that a synthetic Statsig init POST returns 200 in ~3.2 s while the app's own path fails.
Additional finding: the #21722 workaround is no longer viable in 26.903
I tried the local wrapper approach from #21722 (CODEX_NODE_REPL_PATH wrapper injecting "x-codex-browser-use-disable-ambient-network": true into NODE_REPL_REQUEST_META). The mechanism still works — the regenerated [mcp_servers.node_repl] config picks up the wrapper, and the injected metadata is honored.
But in 26.903 this no longer unblocks browser use. It just trades the error:
Reading browser-service.mjs, the reason is visible: nD() (which loads the codex_browser_use_agent_request_header gate) requires hm, the caller-identity promise, which is only set by _w() — and _w() is skipped when ambient network is disabled. The identity comes from GET https://chatgpt.com/backend-api/aura/identity. So in this build, caller identity is a hard prerequisite for the request-header policy, and disabling ambient network initialization cannot work around a Statsig failure anymore.
The exact throw site:
asyncfunctionmk(e){lett=Vr;if(t?.initialization==null)thrownewError("Browser request-header policy requires Statsig initialization.");if(awaitt.initialization,!(awaitbk(t))?.success||t.client.loadingStatus!=="Ready")thrownewError("Unable to load browser request-header policy. Retry the browser command.");
...
}
Side observation
While on a phone-hotspot network (chatgpt.com unreachable), the same broken path also surfaced as js execution timed out; kernel reset, rerun your request — the ambient probe hangs past the ~30 s JS kernel timeout. On a healthy network the hang is gone but the request-header policy error remains, which is why I believe the two messages share the same root cause (Statsig/identity initialization) with different failure modes.
Ask
Please expose the underlying error of the post-login Statsig bootstrap (the current message only says "Timed out"), and/or make the codex_browser_use_agent_request_header gate fail open or degrade to a clearly actionable permission state when the policy cannot be loaded. Happy to provide full logs privately.
Reacted by Chaturna Kasturiratna, sanrandry and chuan-wa
Thanks. It was simply because the VPN was on. 🤦🏻. It works fine now. On Sep 11, 2026, at 6:48 AM, Xinqi Shen ***@***.***> wrote:383196802 left a comment (openai/codex#44112)
+1, reproduced on macOS — confirming keamm1x-sys's reproduction in #44112 with an additional data point (the network path to all Statsig backends is verifiably healthy from the affected machine), plus a working local workaround.
Working local workaround (verified)
Following the short-circuit path keamm1x-sys pointed out in #44112, I found a complete local fix: the extension-side "already enabled" state is just a sticky flag in the extension's own chrome.storage.local:
// extension background.js
var Hn = "AGENT_REQUEST_HEADER_ENABLED";
class {
async isEnabled() {
if (this.enabled) return true;
const e = await chrome.storage.local.get(Hn);
return this.enabled ||= e[Hn] === true, this.enabled;
}
async applyDecision(e) {
return await this.isEnabled() || !e
? this.enabled
: (await chrome.storage.local.set({[Hn]: true}), this.enabled = true, true);
}
}
And on the desktop side (browser-service.mjs, sendSessionRequest), the Statsig policy read is skipped entirely when the extension's getInfo reports agentRequestHeaderEnabled === true:
let i = this.requestHeaderEnabled
|| this.clientInfo.agentRequestHeaderEnabled === true
|| await this.readRequestHeaderEnabled(); // ← skipped via || short-circuit
So pre-seeding the flag does exactly what a successful policy read would have done:
Open chrome://extensions, enable Developer mode;
On the ChatGPT extension card, click Service Worker;
In the DevTools Console, run:
chrome.storage.local.set({AGENT_REQUEST_HEADER_ENABLED: true}, () => chrome.storage.local.get('AGENT_REQUEST_HEADER_ENABLED', console.log))
Retry the browser command in Codex (restart the app once if it still fails, so it re-fetches getInfo).
Verified working on my machine: Chrome control is fully restored after setting the flag. The flag persists across Chrome restarts (it lives in chrome.storage.local). Rollback: chrome.storage.local.remove('AGENT_REQUEST_HEADER_ENABLED').
This also explains why many users never hit the bug: anyone whose extension already holds the sticky flag (from a previously successful policy read) permanently short-circuits the Statsig path. Only users whose flag was never written (fresh extension install, cleared storage, or first use after the regression shipped) hit the failing policy read.
Note on intent: the flag only asserts the agent request header locally; for accounts where the codex_browser_use_agent_request_header gate resolves to true anyway, this restores intended behavior rather than bypassing a restriction. A more robust official fix would be for the desktop side to tolerate policy-load failure (fail open with a cached/last-known decision, or surface a real permission prompt) instead of hard-failing every browser command.
Environment
macOS 15.1 (24B2082), Apple Silicon (arm64)
ChatGPT/Codex desktop app, bundled browser component 26.903.71938
Chrome extension 1.26.901.11451_0 (extension ID hehggadaopoacecdllhhajmbjkdcmajg)
Browser plugin cache: ~/.codex/plugins/cache/openai-bundled/browser/26.903.71938/scripts/browser-service.mjs
ChatGPT Plus account, signed in; model traffic otherwise works normally
Symptom
Controlling external Chrome via the ChatGPT extension fails with:
Unable to load browser request-header policy. Retry the browser command.
Retrying never helps. Full app restart (Cmd+Q) does not help. Resetting the CUA JS session does not help.
Key evidence: not a network problem
The desktop log for the current session shows the same signature as the original report:
error [electron-message-handler] Statsig: error while bootstrapping post-login client
attemptNumber=1 errorMessage="Timed out while fetching post-login Statsig bootstrap"
(~/Library/Logs/com.openai.codex/2026/09/11/codex-desktop-*.log)
However, every endpoint involved in this path is reachable and fast from the same machine at the same time (plain curl, no SDK key, so 403 is expected — the point is TCP/TLS/HTTP all complete in under a second):
Endpoint
Result
https://api.oaistatsig.com/v1/initialize
HTTP 403 in 0.67 s
https://statsigcdn.openai.com/v1
HTTP 403 in 0.37 s
https://ab.chatgpt.com/v1
HTTP 403 in 0.30 s
https://chatgpt.com/backend-api/aura/identity
HTTP 403 in <1 s
So the renderer's post-login Statsig bootstrap times out while the network path to all three Statsig backends is healthy — consistent with the original reporter's finding that a synthetic Statsig init POST returns 200 in ~3.2 s while the app's own path fails.
Additional finding: the #21722 workaround is no longer viable in 26.903
I tried the local wrapper approach from #21722 (CODEX_NODE_REPL_PATH wrapper injecting "x-codex-browser-use-disable-ambient-network": true into NODE_REPL_REQUEST_META). The mechanism still works — the regenerated [mcp_servers.node_repl] config picks up the wrapper, and the injected metadata is honored.
But in 26.903 this no longer unblocks browser use. It just trades the error:
Browser request-header policy requires caller identity.
Reading browser-service.mjs, the reason is visible: nD() (which loads the codex_browser_use_agent_request_header gate) requires hm, the caller-identity promise, which is only set by _w() — and _w() is skipped when ambient network is disabled. The identity comes from GET https://chatgpt.com/backend-api/aura/identity. So in this build, caller identity is a hard prerequisite for the request-header policy, and disabling ambient network initialization cannot work around a Statsig failure anymore.
The exact throw site:
async function mk(e) {
let t = Vr;
if (t?.initialization == null) throw new Error("Browser request-header policy requires Statsig initialization.");
if (await t.initialization, !(await bk(t))?.success || t.client.loadingStatus !== "Ready")
throw new Error("Unable to load browser request-header policy. Retry the browser command.");
...
}
Side observation
While on a phone-hotspot network (chatgpt.com unreachable), the same broken path also surfaced as js execution timed out; kernel reset, rerun your request — the ambient probe hangs past the ~30 s JS kernel timeout. On a healthy network the hang is gone but the request-header policy error remains, which is why I believe the two messages share the same root cause (Statsig/identity initialization) with different failure modes.
Ask
Please expose the underlying error of the post-login Statsig bootstrap (the current message only says "Timed out"), and/or make the codex_browser_use_agent_request_header gate fail open or degrade to a clearly actionable permission state when the policy cannot be loaded. Happy to provide full logs privately.
—Reply to this email directly, view it on GitHub, or unsubscribe.Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you commented.Message ID: ***@***.***>
Additional Windows evidence: intermittent recovery, timeout/cache state, and abort propagation
Adding evidence from a user-authorized diagnostic session on September 12–13, 2026. This is a separate Windows environment; identical error wording does not establish that all reports have the same root cause.
Current versions and environment
Desktop package identified by installed-path entries in the application log: 26.908.4834.0.
An existing local proxy is configured through a project launcher that preserves the official generated environment. A separate launcher-layout compatibility issue was corrected after the official entry point moved into the runtime package. No official component or browser-policy state was modified. This is not an unmodified-launcher baseline, and network/proxy involvement remains possible.
Actual supported-browser observations after a full app restart
Operation
Tool-reported duration
Result
First cua.getState()
24.2758 s
Request-header policy failure
Same-session cua.getState() retry
10.8719 s
Browser inventory returned
Create and read a public Chrome test page
1.7693 s
Actual page content returned
Click its ordinary link and read destination
1.9268 s
Navigation and content verified
The error was:
Unable to load browser request-header policy. Retry the browser command.
No REPL reset or configuration change occurred between these operations. The next call began approximately 32 seconds after the failed output; an explicit sleep accounted for 15.0228 seconds of that interval. This does not establish an optimal or guaranteed 15-second recovery interval. The diagnostic tab was closed.
A separate existing task subsequently made two state-read attempts, taking 22.8569 and 20.0522 seconds, both failing with the same policy error. Their inter-call gap was approximately 4 seconds. There were no business writes in those attempts. Successful recovery in one task therefore did not establish readiness in the other.
Current implementation and isolated SDK findings
Read-only inspection of the current browser bundle still shows 10,000 ms initialization/user-update budgets, a separate latest-update wait, and an SDK network timer race. The readiness boundary checks the latest update's success and the client's Ready state before reading the policy gate. It raises the generic error without retaining the update error as its cause.
Offline tests with public npm @statsig/js-client and @statsig/client-core 3.33.1, verified against registry SHA-512 metadata and using only in-memory responses, reproduced:
Recognized cached fixture values and loadingStatus=Ready while a timed-out refresh returns success=false.
With equal caller/network budgets, the first late response can be ignored by the network race; a later internal retry can populate cache without changing the already-returned failure into success.
An older update can return “User changed during update” while the newest update succeeds. The browser implementation already waits for the latest update, so this alone is not evidence of an identity-race bug.
The public SDK and installed bundle declare the same version but are not byte-identical; the relevant branches were compared, and the public-package tests are not executions of the installed browser service.
New isolated bridge test: cancellation is not propagated by the inspected JavaScript function
The authenticatedFetch JavaScript function embedded in the installed native executable was tested in isolation with mock execution context, an in-memory pending-request map, and a mock host sender replying after 60 ms. No browser service, privileged host connection, real identity, or external network request was used.
Fixture case
Observed result
Signal already aborted before invocation
A mock request was still sent; the fixture response resolved successfully
Signal aborted while waiting for the host
No cancellation message was emitted; the complete fixture response still resolved
Host returns a simulated response-read error
The Promise rejected with the original fixture error text
All three assertions passed. The inspected function serializes method, URL, headers and optional body, but does not serialize a signal or attach a cancellation listener. It constructs a Response only after receiving the complete host body.
This establishes only the JavaScript bridge behavior. The native transport may enforce independent deadlines. It does not establish the cause of an actual policy failure, a connection leak, or measured bandwidth contention. The SDK network override also receives no signal in the inspected request-building branch, so changing only the bridge would not resolve every cancellation path.
The native executable contains distinct request-failed, response-read-failed, response-too-large and HTTP-client-initialization-failed error messages. Their presence does not prove that a particular branch occurred. The response-size limit was not established.
Correlation limits and requested investigation
Desktop logs contained eight IAB route failures during the failed state read, eight during its successful retry, and four during successful Chrome test-page creation. Individual received-to-failed log pairs were approximately 0–1 ms. Those route messages are therefore not sufficient to explain this policy failure.
Independent synthetic initialization probes sometimes received HTTP 200 quickly but did not finish downloading the body within the timeout; a complete synthetic response was approximately 4.2 MB. These were not the real account's browser requests. HTTP status or unauthenticated endpoint reachability alone cannot validate the actual policy path. Neither a native size-limit failure nor a specific network cause is established.
Please investigate:
Preserve allowlisted, sanitized error categories and correlated phase timings at the readiness boundary: request start, first byte, body completion, SDK outcome, latest-update replacement and deadline expiry.
Verify end-to-end cancellation from SDK through bridge to actual transport, including already-aborted requests and cancellation during body reads.
Coordinate total deadlines, internal retries and latest-update completion while retaining identity and policy-freshness checks.
Measure actual response size/encoding and cache reuse before choosing a transport optimization.
Please provide a supported diagnostic path or fixed version. This report does not request bypassing policy checks. No account identifiers, credentials, cookies, private page content, business URLs, raw account logs, or proprietary source excerpts are attached.
I’m seeing the same regression on Windows with external Chrome automation:
Unable to load browser request-header policy. Retry the browser command.
In my case this blocks a previously working authenticated WhatsApp Web automation session. The underlying application workflow remains healthy; only external Chrome control is failing. Restart/reinitialization reproduced the same error. Other automation/session paths continue to work.
This appears consistent with the request-header-policy / Statsig initialization failure described here.
Happy to provide sanitized diagnostic evidence/version details if useful.
In my case, the initial browser connection failed, and a separate test using the application’s built-in browser failed with the same error.
The test only requested opening a simple public webpage and reading its title and content. Browser initialization failed before any page could be opened or read, so the test never reached the target website or its login screen.
Environment
Application shown in the About window: ChatGPT — Powered by Codex & OWL
Application version: 26.903.71938 (release date shown: September 10, 2026)
Operating system: Windows 11 Pro, version 25H2
OS Build: 26200.9457
Last reproduced: September 27, 2026, at 9:16 PM, according to the device’s local clock. Windows is configured to the time zone labelled (UTC+02:00) Beirut; I have not verified the effective UTC offset at the time of the failure.
Troubleshooting and feedback
The permitted recovery attempt did not resolve the error, and the assistant stopped without further retries. No application files, browser policies, or security settings were modified. No website changes were made.
I submitted an in-app bug report successfully:
Feedback ID: 01a0e414-05f0-7c73-8183-4c0910f0e4a4
I’m attaching redacted screenshots showing the application version, Windows version, and time-zone settings.
Is there a supported fix or a recommended diagnostic step for this environment? Please let me know which additional logs would help and how to share them
hello family i found up error in my case , it seems i got this error because i enabled CDP access , restarting working well ater disabled that option !
Additional macOS evidence and a transport-level fix proposal
Related: #44761. This adds evidence for #44112; it does not establish that every report has the same cause.
I investigated this on macOS with desktop version 26.1007.21159 (20052). Browser discovery could work while a page operation failed with Unable to load browser request-header policy. Retry the browser command. Two distinct failures occurred: intermittent endpoint connectivity, and initialization transport/decoding behavior after connectivity recovered.
Observations and limits
In the inspected build, the SDK network budget was approximately 10 seconds, while the native fetch timeout was approximately 30 seconds. The bridge buffered the response body before resolving the JavaScript fetch. A successful HTTP status therefore did not prove initialization finished inside the SDK budget.
Actual initialization responses observed through the authenticated native bridge contained approximately 670–678 KB of compressed bytes. The JavaScript-facing response did not expose Content-Encoding. The original bytes were not JSON; Brotli decompression produced valid JSON of approximately 5.19 MB. Only status, timings, byte counts and parse outcomes were retained for this analysis; no request identities or response bodies are included here.
Adding compression negotiation without accounting for the missing encoding metadata still failed. A narrowly scoped local compatibility experiment that negotiated compression and handled the encoded response subsequently restored browser operations. This was an unsupported installed-resource modification, not a proposed upstream implementation or proof of the final production design.
Three complete desktop/process restarts, each followed by a separate new conversation, passed the first direct Chrome operation and an input/click/readback/cleanup check. Tool durations were 4.401, 4.404 and 4.337 seconds. However, desktop reopening preceded those operations by 141, 230 and 117 seconds because of orchestration. The primary Chrome process, profile and extension persistent state were retained. These are operational acceptance results; they do not demonstrate zero-delay readiness, an empty extension cache, a new Statsig download on every round, or future network stability.
Suggested production changes
1. Make the native transport own the encoding contract. Negotiate only supported response encodings and decode once before returning a Fetch-like response. Normalize encoding/length headers to match the returned bytes. If a bridge deliberately returns raw bytes instead, preserve the encoding metadata and make that contract explicit. Do not make a Statsig-specific JSON/Brotli guessing adapter the permanent HTTP implementation. Enforce a streamed decoded-body limit; a compressed Content-Length check alone is insufficient. Preserve the existing identity, destination authorization, redirect and TLS rules.
2. Propagate cancellation end to end. An already-aborted signal must send no request. An in-flight abort or deadline must cancel the native request/body reader, remove the pending IPC entry and release listeners. Late responses must not settle the promise twice. The SDK override also needs a cancellation source: adding signal support only in the bridge is insufficient if initialization never passes one. Use opaque request IDs scoped to the authorized caller, so cancellation cannot target another session's work.
3. Share one initialization deadline. Carry a monotonic remaining budget through identity readiness, initialization attempts, body reading and retry backoff. Cancel expired attempts before starting another. Avoid stacking SDK and native timeouts that leave abandoned downloads running. A longer generic timeout would only hide this mismatch.
4. Bound duplicate initialization by identity. Coalesce compatible in-flight work for the same authenticated context and configuration generation. On identity changes, cancel or invalidate the older generation; never satisfy a new identity from old results. Preserve the existing latest-user-update readiness checks. This is an architectural recommendation, not a claim that an unhandled identity race has been demonstrated.
5. Preserve actionable, sanitized diagnostics. Distinguish identity failure, connect/TLS failure, deadline expiry, body-read failure, decode failure, body-size rejection and superseded updates. Record phase durations and byte counts without credentials, account identifiers, private URLs, raw headers or configuration payloads. Keep policy failures closed; do not force the gate or pre-seed extension enablement state.
Regression coverage requested
Case
Required result
Plain JSON; gzip; Brotli
One correct decode and consistent response metadata
Missing encoding projection
Contract regression caught before SDK JSON parsing
Truncated/corrupt or oversized decoded body
Bounded failure with a safe error category
Abort before dispatch / during body read
No dispatch / native read terminates; no pending-entry leak
Timeout, retry and late completion
One total budget; no overlapping abandoned attempts or double settlement
Concurrent same-context initialization
One compatible in-flight operation
Identity changes during initialization
Old result cannot satisfy the new context
Fresh runtime and full desktop restart
First real browser operation recorded without prewarming; dispatch delay reported separately
Source ownership
I checked the full public openai/codex checkout at 806d9732c974bc8a51b8317c1bd8985544fe627c, matching the remote HEAD at inspection. It does not contain browser-service.mjs, authenticatedFetch, handle_authenticated_fetch_request or the browser request-header gate implementation. The public shared HTTP transport retains response headers, so changing that module without an established call path would not demonstrate a fix for this bridge.
The current contribution guide directs external contributions to issues and does not accept external PRs. Could the maintainers route this to the desktop/CUA transport owners and confirm which source boundary should implement the encoding, cancellation and deadline changes? No private source excerpts, credentials, account logs, or page content are attached.
I documented a related Windows/Chrome investigation in #52956: #52956.
The report includes the exact Unable to load browser request-header policy error, source-level evidence that Desktop regenerates the built-in node_repl / cua_repl configuration and removes manually configured proxy environment values after restart, the complete version-guarded local patch, and the remediation/verification steps. It also includes a full reusable Codex repair prompt.
Browser acceptance passed locally after applying the environment patch and repairing a missing Chrome native-host configuration. The effects of those interventions were not independently isolated, and independent policy-endpoint requests had succeeded both with and without environment proxy support. This is therefore additional evidence about one configuration issue, not a claim that proxy omission explains every occurrence of this error.
Linking the full report here for maintainers and others investigating the same error.
Additional Windows reproduction on 2026-10-13. I submitted in-app/CLI feedback under thread ID 01a13693-54a4-7372-a291-c0908246836e (without log attachments).
Codex Desktop 26.1007.21434; Chrome extension 1.26.901.11451_0, installed and enabled in the Default profile. The native messaging host is registered and running.
Browser commands fail before tab inspection with Unable to load browser request-header policy. Retry the browser command.
The desktop log at 18:24 UTC records Timed out while fetching post-login Statsig bootstrap after six attempts; one renderer then records browser_use_availability_resolved available=false reason=statsig-disabled.
The failure persists after a full PC restart and clearing the Chrome cache. Basic DNS/TCP/HTTPS connectivity to ab.chatgpt.com works. No Windows proxy or Windows VPN connection is configured. This does not establish why the authenticated bootstrap times out.
Could the team fix the policy/bootstrap failure or provide supported diagnostics and steps to restore Chrome access? Please advise how to collect useful evidence without forcing AGENT_REQUEST_HEADER_ENABLED, which skips the policy read.
Activity
github-actions commentedon Sep 9, 2026
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
jiangyuShiro commentedon Sep 9, 2026
I’m experiencing the same failure on my Windows machine after updating Codex. Browser control worked normally before I updated; afterward, both Chrome and Edge stopped working through Codex. This blocks all browser automation workflows I have tested.
My versions
Reproduction and impact
When I ask Codex to inspect browser state,
cua.getState()repeatedly fails after approximately 20–21 seconds with:I also tested Edge with the profile containing the ChatGPT extension. An explicit
cua.createBrowserTab('edge', 'https://example.com', ...)fails with the same error. Fully restarting Codex and resetting the CUA JavaScript session did not help. This completely blocks browser control on my machine, rather than affecting just one website.Diagnostic findings from troubleshooting with Codex
browser-service.mjsthrows this exact error when Statsig initialization is unsuccessful or the client is not Ready, before obtaining thecodex_browser_use_agent_request_headergate.Timed out while fetching post-login Statsig bootstrap. This is related evidence, not proof that the desktop bootstrap and browser runtime request have the same underlying failure.https://ab.chatgpt.com/v1/initializefrom the bundled Node runtime on my machine returned HTTP 200 and a complete response in approximately 3.2 seconds. This test used a synthetic diagnostic identity. It rules out complete endpoint unreachability at that moment, but does not establish that the browser tool’s own request path is working.I can confirm that browser control worked before the update and failed afterward. I’m reporting this as an update regression; I don’t yet know the exact underlying request exception or which change caused it. Please investigate this shared mandatory initialization path and expose the underlying failure in diagnostics. I have not included credentials, cookies, private page content, or raw account logs.
avimirman-gif commentedon Sep 9, 2026
I am seeing the same request-header-policy failure using Chrome from the ChatGPT desktop app on Windows.
The extension is installed and enabled. Chrome is detected, but the browser-control task reports that it cannot load its request-header policy before opening a harmless public test page. The task reports that no webpage was changed.
The failure persists in a fresh Work chat and after fully quitting and reopening the desktop app. No cause has been established, and I am not attributing it to a particular release or network setting.
In-app feedback was successfully submitted. Feedback ID:
01a08701-e4b3-7ea2-985d-598f41be3c21.Exact desktop-app, Chrome and extension versions have not yet been verified for this report. Please advise whether these diagnostics identify a known issue, a specific affected/fixed version, or a supported next diagnostic step. No account credentials, cookies, tokens, private page content or project information are included here.
keamm1x-sys commentedon Sep 10, 2026
Adding a macOS reproduction of the same error from a user-authorized diagnostic session on September 11, 2026 (Asia/Shanghai).
Environment:
Reproduction:
cua.listTabs({browser: 'chrome'}).Unable to load browser request-header policy. Retry the browser command.A measuredlistTabsattempt took approximately 20.06 seconds.about:blankthrough native UI control and retrying once produces the same error. This reproduces independently of the original website. Earlier Chrome restarts and reconnections did not restore the extension channel.Read-only findings in the bundled
browser-service.mjs:ef.sendSessionRequestreads the request-header policy before dispatching the session request throughsendRequest. This is conditional:getInfois excluded and an already-enabled header setting can short-circuit the policy read.mkwhen the currentreadyresult is unsuccessful orclient.loadingStatus !== 'Ready'. That readiness state can be replaced by a user update. A missing/unrecognized feature gate has a different error, so we have not established a missing gate as the cause.Timed out while fetching post-login Statsig bootstrapand a failed/wham/statsig/bootstrapfetch. These are correlated symptoms, not proof that the desktop bootstrap and browser SDK request share the same underlying failure.Repeated ordinary commands did not recover in this session. However, the code contains an
updateUserAsyncreinitialization path, so we are not claiming that all retries permanently reuse one failed initialization. The browser SDK's underlying HTTP/exception details remain unknown; these observations do not distinguish a client recovery defect, a service response problem, or a request-specific network failure.Native Chrome control did work during the same session, although it also showed a separate intermittent window/accessibility issue. We have not established that the two symptoms share a cause.
Please expose the underlying configuration-initialization failure and advise a supported recovery or fixed version. No request-header gate, browser security setting, or user profile data was modified. No credentials, cookies, private page content, raw logs, or account/session identifiers are included in this report.
gongzhang commentedon Sep 11, 2026
Also reproducible on macOS with Codex desktop version 26.903.71938.
The built-in Chrome browser API consistently fails before page interaction:
cua.getState()returns an empty browser list plus the policy error after approximately 20 seconds.cua.createBrowserTab("chrome", "https://www.xiaohongshu.com/explore", { sessionName: "Connection test" })fails with the same error after approximately 20 seconds.Updating and restarting Codex, and reinstalling the Chrome extension, did not resolve it. Local extension/native-host diagnostics previously reported the extension enabled and the native messaging host correctly configured.
As a comparison, Chrome DevTools MCP with
--autoConnectworks on the same machine and existing Chrome profile: it can list tabs, open a page, and read page content. A persistent MCP session also successfully handled successive calls. This is a working alternative connection path, not a fix for the built-in browser integration.In-app feedback has been submitted. Feedback ID:
01a08e9c-c155-75b3-bc67-8e22d0d7fe93.383196802 commentedon Sep 11, 2026
+1, reproduced on macOS — confirming keamm1x-sys's reproduction in #44112 with an additional data point (the network path to all Statsig backends is verifiably healthy from the affected machine), plus a working local workaround.
Working local workaround (verified)
Following the short-circuit path keamm1x-sys pointed out in #44112, I found a complete local fix: the extension-side "already enabled" state is just a sticky flag in the extension's own
chrome.storage.local:And on the desktop side (
browser-service.mjs,sendSessionRequest), the Statsig policy read is skipped entirely when the extension'sgetInforeportsagentRequestHeaderEnabled === true:So pre-seeding the flag does exactly what a successful policy read would have done:
Open
chrome://extensions, enable Developer mode;On the ChatGPT extension card, click Service Worker;
In the DevTools Console, run:
Retry the browser command in Codex (restart the app once if it still fails, so it re-fetches
getInfo).Verified working on my machine: Chrome control is fully restored after setting the flag. The flag persists across Chrome restarts (it lives in
chrome.storage.local). Rollback:chrome.storage.local.remove('AGENT_REQUEST_HEADER_ENABLED').This also explains why many users never hit the bug: anyone whose extension already holds the sticky flag (from a previously successful policy read) permanently short-circuits the Statsig path. Only users whose flag was never written (fresh extension install, cleared storage, or first use after the regression shipped) hit the failing policy read.
Note on intent: the flag only asserts the agent request header locally; for accounts where the
codex_browser_use_agent_request_headergate resolves totrueanyway, this restores intended behavior rather than bypassing a restriction. A more robust official fix would be for the desktop side to tolerate policy-load failure (fail open with a cached/last-known decision, or surface a real permission prompt) instead of hard-failing every browser command.Environment
26.903.719381.26.901.11451_0(extension IDhehggadaopoacecdllhhajmbjkdcmajg)~/.codex/plugins/cache/openai-bundled/browser/26.903.71938/scripts/browser-service.mjsSymptom
Controlling external Chrome via the ChatGPT extension fails with:
Retrying never helps. Full app restart (Cmd+Q) does not help. Resetting the CUA JS session does not help.
Key evidence: not a network problem
The desktop log for the current session shows the same signature as the original report:
(
~/Library/Logs/com.openai.codex/2026/09/11/codex-desktop-*.log)However, every endpoint involved in this path is reachable and fast from the same machine at the same time (plain
curl, no SDK key, so 403 is expected — the point is TCP/TLS/HTTP all complete in under a second):https://api.oaistatsig.com/v1/initializehttps://statsigcdn.openai.com/v1https://ab.chatgpt.com/v1https://chatgpt.com/backend-api/aura/identitySo the renderer's post-login Statsig bootstrap times out while the network path to all three Statsig backends is healthy — consistent with the original reporter's finding that a synthetic Statsig init POST returns 200 in ~3.2 s while the app's own path fails.
Additional finding: the #21722 workaround is no longer viable in 26.903
I tried the local wrapper approach from #21722 (
CODEX_NODE_REPL_PATHwrapper injecting"x-codex-browser-use-disable-ambient-network": trueintoNODE_REPL_REQUEST_META). The mechanism still works — the regenerated[mcp_servers.node_repl]config picks up the wrapper, and the injected metadata is honored.But in 26.903 this no longer unblocks browser use. It just trades the error:
Reading
browser-service.mjs, the reason is visible:nD()(which loads thecodex_browser_use_agent_request_headergate) requireshm, the caller-identity promise, which is only set by_w()— and_w()is skipped when ambient network is disabled. The identity comes fromGET https://chatgpt.com/backend-api/aura/identity. So in this build, caller identity is a hard prerequisite for the request-header policy, and disabling ambient network initialization cannot work around a Statsig failure anymore.The exact throw site:
Side observation
While on a phone-hotspot network (chatgpt.com unreachable), the same broken path also surfaced as
js execution timed out; kernel reset, rerun your request— the ambient probe hangs past the ~30 s JS kernel timeout. On a healthy network the hang is gone but the request-header policy error remains, which is why I believe the two messages share the same root cause (Statsig/identity initialization) with different failure modes.Ask
Please expose the underlying error of the post-login Statsig bootstrap (the current message only says "Timed out"), and/or make the
codex_browser_use_agent_request_headergate fail open or degrade to a clearly actionable permission state when the policy cannot be loaded. Happy to provide full logs privately.avimirman-gif commentedon Sep 11, 2026
Jerryzhang460 commentedon Sep 13, 2026
Additional Windows evidence: intermittent recovery, timeout/cache state, and abort propagation
Adding evidence from a user-authorized diagnostic session on September 12–13, 2026. This is a separate Windows environment; identical error wording does not establish that all reports have the same root cause.
Current versions and environment
browser-service.mjs: 1,315,151 bytes; SHA-2563e6fd4a8cf09f57549d63f2c9cbfa2abf42f0a6b0c09c3d6605fe07c8ba09e4a.node_repl.exe: SHA-256af8da68ea0802f72bd58906ef75bf38180493222dd26da57684d5391ef8799eb.Actual supported-browser observations after a full app restart
cua.getState()cua.getState()retryThe error was:
No REPL reset or configuration change occurred between these operations. The next call began approximately 32 seconds after the failed output; an explicit sleep accounted for 15.0228 seconds of that interval. This does not establish an optimal or guaranteed 15-second recovery interval. The diagnostic tab was closed.
A separate existing task subsequently made two state-read attempts, taking 22.8569 and 20.0522 seconds, both failing with the same policy error. Their inter-call gap was approximately 4 seconds. There were no business writes in those attempts. Successful recovery in one task therefore did not establish readiness in the other.
Current implementation and isolated SDK findings
Read-only inspection of the current browser bundle still shows 10,000 ms initialization/user-update budgets, a separate latest-update wait, and an SDK network timer race. The readiness boundary checks the latest update's success and the client's Ready state before reading the policy gate. It raises the generic error without retaining the update error as its cause.
Offline tests with public npm
@statsig/js-clientand@statsig/client-core3.33.1, verified against registry SHA-512 metadata and using only in-memory responses, reproduced:loadingStatus=Readywhile a timed-out refresh returnssuccess=false.The public SDK and installed bundle declare the same version but are not byte-identical; the relevant branches were compared, and the public-package tests are not executions of the installed browser service.
New isolated bridge test: cancellation is not propagated by the inspected JavaScript function
The
authenticatedFetchJavaScript function embedded in the installed native executable was tested in isolation with mock execution context, an in-memory pending-request map, and a mock host sender replying after 60 ms. No browser service, privileged host connection, real identity, or external network request was used.All three assertions passed. The inspected function serializes method, URL, headers and optional body, but does not serialize a signal or attach a cancellation listener. It constructs a Response only after receiving the complete host body.
This establishes only the JavaScript bridge behavior. The native transport may enforce independent deadlines. It does not establish the cause of an actual policy failure, a connection leak, or measured bandwidth contention. The SDK network override also receives no signal in the inspected request-building branch, so changing only the bridge would not resolve every cancellation path.
The native executable contains distinct request-failed, response-read-failed, response-too-large and HTTP-client-initialization-failed error messages. Their presence does not prove that a particular branch occurred. The response-size limit was not established.
Correlation limits and requested investigation
Desktop logs contained eight IAB route failures during the failed state read, eight during its successful retry, and four during successful Chrome test-page creation. Individual received-to-failed log pairs were approximately 0–1 ms. Those route messages are therefore not sufficient to explain this policy failure.
Independent synthetic initialization probes sometimes received HTTP 200 quickly but did not finish downloading the body within the timeout; a complete synthetic response was approximately 4.2 MB. These were not the real account's browser requests. HTTP status or unauthenticated endpoint reachability alone cannot validate the actual policy path. Neither a native size-limit failure nor a specific network cause is established.
Please investigate:
Please provide a supported diagnostic path or fixed version. This report does not request bypassing policy checks. No account identifiers, credentials, cookies, private page content, business URLs, raw account logs, or proprietary source excerpts are attached.
apartmint21 commentedon Sep 14, 2026
I’m seeing the same regression on Windows with external Chrome automation:
Unable to load browser request-header policy. Retry the browser command.
In my case this blocks a previously working authenticated WhatsApp Web automation session. The underlying application workflow remains healthy; only external Chrome control is failing. Restart/reinitialization reproduced the same error. Other automation/session paths continue to work.
This appears consistent with the request-header-policy / Statsig initialization failure described here.
Happy to provide sanitized diagnostic evidence/version details if useful.
Codex Version 26.908.40834
Released 11 Sept 2026
charel-ship-it commentedon Sep 27, 2026
I’m also experiencing this error on Windows:
Unable to load browser request-header policyIn my case, the initial browser connection failed, and a separate test using the application’s built-in browser failed with the same error.
The test only requested opening a simple public webpage and reading its title and content. Browser initialization failed before any page could be opened or read, so the test never reached the target website or its login screen.
Environment
Last reproduced: September 27, 2026, at 9:16 PM, according to the device’s local clock. Windows is configured to the time zone labelled
(UTC+02:00) Beirut; I have not verified the effective UTC offset at the time of the failure.Troubleshooting and feedback
The permitted recovery attempt did not resolve the error, and the assistant stopped without further retries. No application files, browser policies, or security settings were modified. No website changes were made.
I submitted an in-app bug report successfully:
Feedback ID:
01a0e414-05f0-7c73-8183-4c0910f0e4a4I’m attaching redacted screenshots showing the application version, Windows version, and time-zone settings.
Is there a supported fix or a recommended diagnostic step for this environment? Please let me know which additional logs would help and how to share them
privately.
samyarkd commentedon Oct 1, 2026
I have the same error with the latest version available to this date several older versions.
ngdream commentedon Oct 8, 2026
hello family i found up error in my case , it seems i got this error because i enabled CDP access , restarting working well ater disabled that option !
clsaa commentedon Oct 10, 2026
Additional macOS evidence and a transport-level fix proposal
Related: #44761. This adds evidence for #44112; it does not establish that every report has the same cause.
I investigated this on macOS with desktop version 26.1007.21159 (20052). Browser discovery could work while a page operation failed with
Unable to load browser request-header policy. Retry the browser command.Two distinct failures occurred: intermittent endpoint connectivity, and initialization transport/decoding behavior after connectivity recovered.Observations and limits
Content-Encoding. The original bytes were not JSON; Brotli decompression produced valid JSON of approximately 5.19 MB. Only status, timings, byte counts and parse outcomes were retained for this analysis; no request identities or response bodies are included here.Suggested production changes
1. Make the native transport own the encoding contract. Negotiate only supported response encodings and decode once before returning a Fetch-like response. Normalize encoding/length headers to match the returned bytes. If a bridge deliberately returns raw bytes instead, preserve the encoding metadata and make that contract explicit. Do not make a Statsig-specific JSON/Brotli guessing adapter the permanent HTTP implementation. Enforce a streamed decoded-body limit; a compressed Content-Length check alone is insufficient. Preserve the existing identity, destination authorization, redirect and TLS rules.
2. Propagate cancellation end to end. An already-aborted signal must send no request. An in-flight abort or deadline must cancel the native request/body reader, remove the pending IPC entry and release listeners. Late responses must not settle the promise twice. The SDK override also needs a cancellation source: adding signal support only in the bridge is insufficient if initialization never passes one. Use opaque request IDs scoped to the authorized caller, so cancellation cannot target another session's work.
3. Share one initialization deadline. Carry a monotonic remaining budget through identity readiness, initialization attempts, body reading and retry backoff. Cancel expired attempts before starting another. Avoid stacking SDK and native timeouts that leave abandoned downloads running. A longer generic timeout would only hide this mismatch.
4. Bound duplicate initialization by identity. Coalesce compatible in-flight work for the same authenticated context and configuration generation. On identity changes, cancel or invalidate the older generation; never satisfy a new identity from old results. Preserve the existing latest-user-update readiness checks. This is an architectural recommendation, not a claim that an unhandled identity race has been demonstrated.
5. Preserve actionable, sanitized diagnostics. Distinguish identity failure, connect/TLS failure, deadline expiry, body-read failure, decode failure, body-size rejection and superseded updates. Record phase durations and byte counts without credentials, account identifiers, private URLs, raw headers or configuration payloads. Keep policy failures closed; do not force the gate or pre-seed extension enablement state.
Regression coverage requested
Source ownership
I checked the full public
openai/codexcheckout at806d9732c974bc8a51b8317c1bd8985544fe627c, matching the remote HEAD at inspection. It does not containbrowser-service.mjs,authenticatedFetch,handle_authenticated_fetch_requestor the browser request-header gate implementation. The public shared HTTP transport retains response headers, so changing that module without an established call path would not demonstrate a fix for this bridge.The current contribution guide directs external contributions to issues and does not accept external PRs. Could the maintainers route this to the desktop/CUA transport owners and confirm which source boundary should implement the encoding, cancellation and deadline changes? No private source excerpts, credentials, account logs, or page content are attached.
ZzuMrW commentedon Oct 10, 2026
I documented a related Windows/Chrome investigation in #52956: #52956.
The report includes the exact
Unable to load browser request-header policyerror, source-level evidence that Desktop regenerates the built-innode_repl/cua_replconfiguration and removes manually configured proxy environment values after restart, the complete version-guarded local patch, and the remediation/verification steps. It also includes a full reusable Codex repair prompt.Browser acceptance passed locally after applying the environment patch and repairing a missing Chrome native-host configuration. The effects of those interventions were not independently isolated, and independent policy-endpoint requests had succeeded both with and without environment proxy support. This is therefore additional evidence about one configuration issue, not a claim that proxy omission explains every occurrence of this error.
Linking the full report here for maintainers and others investigating the same error.
renatoyonamine commentedon Oct 13, 2026
Additional Windows reproduction on 2026-10-13. I submitted in-app/CLI feedback under thread ID
01a13693-54a4-7372-a291-c0908246836e(without log attachments).26.1007.21434; Chrome extension1.26.901.11451_0, installed and enabled in theDefaultprofile. The native messaging host is registered and running.Unable to load browser request-header policy. Retry the browser command.Timed out while fetching post-login Statsig bootstrapafter six attempts; one renderer then recordsbrowser_use_availability_resolved available=false reason=statsig-disabled.ab.chatgpt.comworks. No Windows proxy or Windows VPN connection is configured. This does not establish why the authenticated bootstrap times out.Could the team fix the policy/bootstrap failure or provide supported diagnostics and steps to restore Chrome access? Please advise how to collect useful evidence without forcing
AGENT_REQUEST_HEADER_ENABLED, which skips the policy read.