Skip to main content

Codex Token Exchange Failed 403: Diagnose Login, Proxy, Region, and Cached Auth

A
12 min readAI Development Tools

A rapid, evidence-first recovery path for Codex sign-in 403 that protects credentials and replaces random fixes with proof.

Codex Token Exchange Failed 403: Diagnose Login, Proxy, Region, and Cached Auth

Token exchange failed: token endpoint returned status 403 Forbidden means an authentication request was refused, but the error alone does not prove an OpenAI outage, a proxy problem, a region restriction, or stale credentials. First identify whether the failure happened at the localhost callback, the outbound token exchange, or the first authenticated Codex request. Before resetting anything, record codex --version, run codex login status, note where Codex is actually running, check the status page, and preserve the redacted response body. Do not delete ~/.codex, disable TLS verification, bypass a region restriction, or share a callback URL or token while the rejecting hop is still unknown.

What you sawFailing hopFirst useful check
The browser never returned to Codexlocalhost callbackIs the listener running in the same environment as the browser callback?
The browser approved sign-in, then Codex printed the exact token-exchange 403outbound token exchangeInspect the response body, proxy/WAF path, CA trust, region/account policy, and execution environment
Login completed, but the first Codex request returned 403authenticated requestCheck workspace entitlement, provider route, model access, and which credential source won

The distinction matters because a localhost callback problem is not a token-endpoint rejection, and a later API 403 is not a failed exchange. Fix the hop you can prove. Stop changing network settings if the response body names an account, workspace, policy, or supported-country boundary.

Verified 2026-07-12: the official OpenAI status page showed no known system-wide incident during this review. That is a useful first check, not proof that your specific network, account, workspace, or region route is healthy.

The seven-minute recovery sequence

Work in this order. It preserves evidence and makes each change reversible.

1. Record the client and current auth state

Run these commands in the same shell, container, WSL distribution, SSH host, or desktop environment where the failure occurred:

bash
codex --version codex login status

The current-run probe returned codex-cli 0.144.0-alpha.4; that is an observation, not a minimum supported version. Record your own output. A stale build is worth updating, but "update everything" is not a diagnosis.

If codex login status already reports the expected route, test one small authenticated request before starting a new login. You may be looking at an old terminal error rather than a current failure.

2. Check current service status

Open the OpenAI status page and note the timestamp. If an authentication or Codex incident is active, preserve your evidence and wait for the incident to clear before rewriting local configuration. If the page is green, continue; aggregate status cannot see a corporate proxy, local certificate chain, account policy, or workspace restriction.

3. Name the execution owner

Write down where the codex process actually runs:

  • macOS, Windows, or Linux directly
  • WSL, a container, or a remote SSH host
  • an IDE terminal, CI runner, or managed developer environment

The browser may run on your laptop while Codex and its callback listener run elsewhere. If the browser approved sign-in but cannot reach the listener, you have a callback topology problem. If Codex received the callback and then reports that the token endpoint returned 403, the outbound exchange left the execution owner and was rejected later in the route.

4. Preserve the response without preserving secrets

Keep the exact status, timestamp with time zone, command, Codex version, and any short error code or request ID. Redact:

  • authorization codes and access or refresh tokens
  • the full callback URL and query string
  • cookies, API keys, email addresses, organization IDs, and unrelated file paths

The response body can decide the branch. A named country/region policy, account restriction, workspace denial, or proxy-branded block page is more useful than the number 403 alone.

5. Retry once on a clean, known route

After recording evidence, make one controlled retry. Change only one owner: current Codex build, direct versus managed network, correct execution environment, trusted corporate CA, or clean credential state. Verify the same route afterward.

A fix passes only when login completes and this command reports the expected authentication method in the same environment:

bash
codex login status

Repeated blind login attempts can rotate codes and destroy the clean comparison you need.

How the Codex sign-in route actually fails

Four-hop Codex authentication route from browser authorization to first authenticated request

Treat Codex sign-in as five observable steps:

  1. Codex opens a browser authorization flow.
  2. The browser returns an authorization result to a local callback listener.
  3. Codex sends an outbound token request that trades the short-lived code for credentials.
  4. Codex stores credentials using its configured credential store.
  5. Codex makes its first authenticated request.

The exact token-exchange message belongs to step 3. This narrows the investigation, but it still leaves multiple rejecting layers: OpenAI policy or account controls, a corporate proxy/WAF, TLS interception and CA trust, the wrong runtime or route, or stale state that caused the exchange to use an invalid context.

OpenAI's Codex authentication documentation explains the supported sign-in routes and credential storage choices. Its environment-variable reference documents CODEX_CA_CERTIFICATE for a custom certificate authority bundle. Those official controls are safer than disabling certificate verification.

Branch matrix: proof, action, success, stop

Recovery matrix for proxy, CA, runtime, region, workspace, and cached-auth branches

BranchEvidence that points hereBounded actionSuccess signalStop rule
proxy or WAFproxy-branded HTML, corporate block ID, route works on a permitted direct networkask the network owner to allow the required auth route; keep localhost callback traffic localone clean login succeeds on the approved routedo not tunnel around organizational policy
corporate CAcertificate-chain errors, TLS inspection is documented, failure begins on managed networkset CODEX_CA_CERTIFICATE to the approved PEM bundleexchange completes with verification still enablednever use an insecure TLS flag
WSL, container, or remote hostbrowser and callback listener live in different network namespacesrun login where callback reachability is correct, or use an officially supported alternative auth flowcallback reaches the same Codex processdo not expose a callback listener publicly
country, region, or account policyresponse body names unsupported_country_region_territory or an account restrictionverify the account and supported-country list; use support for mistakesofficial route becomes eligible or support resolves the recorddo not use a VPN or borrowed account to bypass the boundary
managed workspacepersonal route works but SSO/workspace route is denied, or the body names workspace policyask the workspace administrator to confirm Codex access and identity policyexpected workspace auth succeedsstop local proxy edits when policy is explicit
stale credential stateroute and policy checks pass; logout/login changes the behavioruse codex logout, then perform one clean codex loginstatus reports the intended route and a request succeedsdo not delete the whole ~/.codex directory first

Proxy handling: separate loopback from outbound traffic

A common mistake is to add every authentication hostname to NO_PROXY. The localhost callback and the outbound token exchange have opposite needs.

If your environment requires a proxy, loopback traffic should usually stay local:

bash
export NO_PROXY="localhost,127.0.0.1,::1"

But the outbound token request may still need the approved corporate proxy. Do not blindly bypass it. An OpenAI collaborator documented a Codex case where a proxy prevented access to localhost and recommended allowing the callback ports or using an alternative authentication path. That supports a topology check; it does not prove every 403 is caused by a proxy.

Check proxy variables without publishing their credentials:

bash
env | grep -iE '^(HTTP|HTTPS|ALL|NO)_PROXY='

If the value contains usernames, passwords, or internal hosts, redact it before sharing.

Corporate TLS inspection: trust the approved CA

When a company legitimately intercepts TLS, obtain the approved PEM certificate bundle from the network or security team and point Codex to it:

bash
export CODEX_CA_CERTIFICATE="/path/to/company-ca-bundle.pem" codex login

OpenAI's current Codex environment reference also lists standard certificate variables as fallback mechanisms, but CODEX_CA_CERTIFICATE is the Codex-specific control to prefer. A certificate failure and an HTTP 403 are different signals; use this branch when chain or interception evidence exists, not as a universal fix.

Region, account, and workspace boundaries

If the response explicitly names a country or territory, compare the account's real location and access route with OpenAI's current supported-country list. A supported-country page is volatile, so check it on the day you troubleshoot. If the account should be eligible, contact support with the redacted response and timestamp.

For a managed Business, Enterprise, Edu, or SSO workspace, ask the administrator whether Codex is enabled for the expected identity and whether the organization requires a specific login route. An administrator policy cannot be repaired by deleting a local cache.

Reset only the credential layer you mean to reset

The reversible reset is:

bash
codex logout codex login

Do not start with rm -rf ~/.codex. That directory can include configuration, state, logs, and other context you may need. A community workaround that deletes the entire directory can appear to help while erasing the evidence that distinguishes credentials from proxy, policy, or runtime ownership.

If you need to inspect where Codex keeps state and configuration before changing anything, see the Codex config.toml guide. Treat credential files as secrets: do not copy another person's auth.json, paste it into a ticket, sync it through chat, or commit it.

Alternative authentication routes and their tradeoffs

The CLI build checked on 2026-07-12 exposed these login options:

bash
codex login --device-auth codex login --with-api-key codex login --with-access-token

Use only a route authorized for your environment.

  • Device authentication can help when browser-to-localhost topology is the blocker. It is not a way around an account or country policy.
  • API-key login is a developer-billing route. It can have different feature, billing, and workspace behavior from ChatGPT subscription login. Read Codex API key vs subscription before treating it as equivalent.
  • Access-token login is appropriate only for a trusted, documented automation or enterprise flow. Do not paste an access token into shell history or a public issue.

If you use an API key, pipe it without printing it:

bash
printenv OPENAI_API_KEY | codex login --with-api-key

Changing authentication routes is a product decision, not proof that the original route was fixed. It can also change which Codex usage limits and billing contract apply.

What to send support or your administrator

Redacted support evidence pack for a Codex token exchange 403

Escalate immediately when the body identifies account, workspace, country/region, or policy rejection. Otherwise, escalate after one clean retry on a current build and an approved route.

Send a compact evidence pack:

  • exact error text and redacted response body
  • timestamp with time zone
  • codex --version and the intended authentication mode
  • OS plus execution owner: host, WSL, container, remote, IDE, or CI
  • whether the browser callback returned successfully
  • whether a corporate proxy, WAF, VPN, or TLS inspection is present
  • request ID, support thread ID, or Codex /feedback thread ID when available
  • one controlled change you tried and its result

Never attach the callback URL, authorization code, token, API key, cookie, complete auth.json, or unredacted proxy URL. In a public GitHub issue, keep the evidence even narrower.

FAQ

Does a token exchange 403 mean OpenAI is down?

No. It proves a request was refused at the exchange route. Check the current status page, but also inspect the response body, network path, account/workspace policy, region eligibility, and execution environment.

Why did the browser say login succeeded while Codex failed?

Browser authorization and token exchange are separate hops. The browser can approve the user while the outbound code-for-token request is later rejected by a proxy, policy layer, account rule, or stale context.

Should I add OpenAI domains to NO_PROXY?

Not blindly. Keep loopback names such as localhost, 127.0.0.1, and ::1 local when appropriate. The outbound token endpoint may be required to traverse your approved proxy. Confirm the corporate routing policy before changing it.

Should I delete ~/.codex?

Not as a first action. Preserve evidence, use codex logout, and retry one clean login. Inspect configuration and state deliberately if the credential-only reset does not help.

Can I switch to an API key to get around the 403?

You can use API-key authentication when it is supported and fits your task, but it changes billing and feature context. It does not override account, workspace, or supported-country policy and does not prove the ChatGPT login route is repaired.

When should I stop troubleshooting locally?

Stop immediately if the response names a policy, account, workspace, or country/region denial. Otherwise stop after one clean current-build retry on an approved route fails with the same evidence. At that point, send the redacted evidence pack to OpenAI Support, your workspace administrator, or the network owner who controls the rejecting layer.

The shortest safe rule is: identify the hop, preserve the body, change one owner, verify the same route, and stop at policy boundaries.

#OpenAI Codex#Codex CLI#Token Exchange#403 Forbidden#OAuth#Troubleshooting
Share: