Skip to content

Codex CLI Proxy Configuration Troubleshooting: A Complete Account of a 401 Error and the Pitfalls I Encountered

When connecting to third-party relay servers with the new Codex CLI (tested with v0.145.0), the most common error is a series of 401 responses. This article outlines the correct way to write the `config.toml` file, three common pitfalls, and verification methods—you can use it as a troubleshooting checklist and copy the instructions directly.

Reading Time
7 min read
Updated
2026.08.04

In short

The key to connecting Codex CLI to third-party relay servers is: the `base_url` must be written inside the [model_providers.xxx] block and referenced by the top-level `model_provider`; if written directly at the top level, it will be completely ignored by the new version. Use the top-level `experimental_bearer_token` for authentication; do not rely on environment variables.

Troubleshooting Codex CLI Integration with a Relay Server

When setting up the new version of Codex CLI to connect to a third-party relay server, users often get stuck at one point: even though they’ve entered the relay server’s address and key, requests still end up at api.openai.com, followed by a series of 401 Unauthorized errors.

This article documents my complete process of connecting Codex CLI (including the Codex built into the ChatGPT desktop app; tested with v0.145.0) to a relay server: the correct configuration syntax, three common pitfalls, and how to verify that the connection is working properly. You can use this as a troubleshooting checklist and follow the steps exactly.

Conclusion First: The Correct config.toml The configuration file is located at ~/.codex/config.toml (C:\Users\你\.codex\config.toml on Windows). Here is the minimal configuration that works:

model = "gpt-5.6-sol"          # 换成中转站支持的模型名
model_reasoning_effort = "high"
model_provider = "qnvip"       # 指向下面的 provider 块
experimental_bearer_token = 'sk-xxxxxxxx'   # 中转站的 key,鉴权用

[model_providers.qnvip]
name = "qnvip"
base_url = "http://中转站域名/v1"
wire_api = "responses"         # 中转站不支持 responses 就改成 "chat"

Structurally, there are only three things that must align:

  1. The value of the top-level model_provider is equal to the xxx value inside [model_providers.xxx].
  2. base_url is defined inside the provider block, not at the top level.
  3. Authentication uses the top-level experimental_bearer_token and does not rely on environment variables.

What the Error Looks Like

When a connection fails, the most common error message looks like this:

Error

exit invalid_api_key

请求根本没走中转站

401 Unauthorized: Incorrect API key provided: sk-xxxx...
Path
https://api.openai.com/v1/responses
Notes
  • 报错里的 url 是 api.openai.com,而不是你的中转站域名
  • 说明 Codex 用的是内置 openai provider,没读到你的配置
  • 中转站的 key 拿到官方接口当然无效 → 401

Three Common Pitfalls

Pitfall 1: base_url Written directly at the top level → Completely ignored (Main Cause)

This is where the vast majority of people get stuck. The new version of Codex does not recognize the top-level base_url. If there is no [model_providers.xxx] block with a reference to model_provider, it falls back to the built-in OpenAI provider, which is hardcoded to api.openai.com.

ApproachResult
❌ base_url Written directly at the top levelSilently ignored with no error messages; request routed to api.openai.com, resulting in a 401
✅ base_url Written inside the [model_providers.xxx] blockWorks in conjunction with model_provider at the top level; request correctly routed to the relay station

Incorrect Syntax (Directly written at the top level; invalid):

base_url = "http://中转站域名/v1"   # ❌ 被忽略
wire_api = "responses"

Pitfall 2: An Extra Quotation Mark at the End of the Key

It’s very easy to make a typo when copying and pasting a key. For example, with 'sk-...4eb5"' — the extra " at the end will be treated as part of the key, corrupting the entire key. As a result, even if the provider is paired correctly, the relay will report invalid_api_key.

Pitfall 3: Custom Provider Not Reading auth.json In the Codex built into the ChatGPT desktop app, there’s a auth.json, and the OPENAI_API_KEY within it is exclusively for the built-in OpenAI provider. If a custom provider specifies env_key = "OPENAI_API_KEY", it reads the actual system environment variables instead of auth.json, resulting in the following error:

Missing environment variable: OPENAI_API_KEY

Two Solutions—I Recommend the First One:

  • ✅ Use top-level experimental_bearer_token: No reliance on environment variables; works reliably whether launched from the command line or via the desktop app.
  • ⚠️ Alternatively, use export OPENAI_API_KEY=sk-xxx and then specify env_key = "OPENAI_API_KEY" in the provider. Note that when launching the desktop app, it may not inherit the exports from ~/.zshrc, which can cause inconsistent behavior.

Configuration Process Overview

Translating the three pitfalls above into step-by-step instructions results in the following path:

  1. Completed: 写 provider 块

    在 [model_providers.xxx] 里填 name、base_url、wire_api

  2. Completed: 顶层指向 provider

    设置 model_provider = "xxx",与块名一致

  3. Completed: 配置鉴权

    用 experimental_bearer_token 填中转站 key,检查引号成对

  4. Current: 在受信任目录验证

    用 codex exec 跑一条测试请求,确认 provider 生效

Verification Methods

It must be run in a trusted directory; otherwise, it will return Not inside a trusted directory:

cd /受信任的项目目录
echo "只回复两个字:成功" | codex exec --skip-git-repo-check

Check the startup logs to see if “provider:” is your relay station name and whether content is being returned normally. If you see the word “Success,” it means the entire connection is working properly.

Quick Reference Table for Errors

I’ve compiled a table of common errors and their corresponding causes—if you run into a problem, just check the table to see what it is:

ErrorCauseResolution
401 and the URL is api.openai.combase_url Did not enter the provider block / provider not activeCheck if model_provider and [model_providers.xxx] match
401 invalid_api_key (URL is a relay server)Incorrect key / key contains extra charactersRecopy the key and ensure all quotation marks are properly paired
Missing environment variable: OPENAI_API_KEYenv_key is used but environment variables are not setSwitch to experimental_bearer_token
404 / Incorrect pathwire_api is set to responses, but the relay server only supports "chat"Change to "chat"; or check if /v1 is missing or extra in base_url
Not inside a trusted directoryNot in a trusted directoryAdd --skip-git-repo-check or run it from a trusted directory

Keep reading