openai/codex · error
Environment variable {env_var} for MCP server '{server_name}
Error message
Environment variable {env_var} for MCP server '{server_name}' is empty What it means
Thrown while starting an MCP server whose config declares bearer_token_env_var for the streamable-http transport. resolve_bearer_token found the variable in the process environment, but its value is the empty string. An empty Bearer credential can never authenticate, so Codex fails the server at startup instead of sending a guaranteed-401 request later.
Source
Thrown at codex-rs/codex-mcp/src/rmcp_client.rs:842
}
}
fn is_untrusted_connector_meta_key(key: &str) -> bool {
UNTRUSTED_CONNECTOR_META_KEYS.contains(&key)
}
fn resolve_bearer_token(
server_name: &str,
bearer_token_env_var: Option<&str>,
) -> Result<Option<String>> {
let Some(env_var) = bearer_token_env_var else {
return Ok(None);
};
match env::var(env_var) {
Ok(value) => {
if value.is_empty() {
Err(anyhow!(
"Environment variable {env_var} for MCP server '{server_name}' is empty"
))
} else {
Ok(Some(value))
}
}
Err(env::VarError::NotPresent) => Err(anyhow!(
"Environment variable {env_var} for MCP server '{server_name}' is not set"
)),
Err(env::VarError::NotUnicode(_)) => Err(anyhow!(
"Environment variable {env_var} for MCP server '{server_name}' contains invalid Unicode"
)),
}
}
fn validate_mcp_server_name(server_name: &str) -> Result<()> {
let re = regex_lite::Regex::new(r"^[a-zA-Z0-9_-]+$")?;
if !re.is_match(server_name) {View on GitHub (pinned to 339751715c)
Solutions
- Export a real value: FOO_TOKEN=<actual-token> codex (or put it in the shell profile / .env the launcher reads) and restart so the MCP server retries startup
- Grep launch files for an empty assignment: grep -rn 'FOO_TOKEN=$' ~/.bashrc .env docker-compose.yml, and fill in the value
- If this server does not use bearer auth, delete bearer_token_env_var from its [mcp_servers.NAME] entry
- If the token should come from the remote executor, configure it in the executor environment (which must advertise http_header_env_vars) instead of the local one
Example fix
# before (.env) FOO_TOKEN= # after FOO_TOKEN=ghp_0123456789abcdef
Defensive patterns
Strategy: validation
Validate before calling
#!/usr/bin/env bash
# Fail fast before Codex ever starts the MCP server
: "${FOO_TOKEN:?FOO_TOKEN must be set and non-empty for MCP server 'foo'}"
if [ -z "$FOO_TOKEN" ]; then echo "FOO_TOKEN is empty" >&2; exit 1; fi
exec codex "$@" Try / catch
let token = resolve_bearer_token(server, bearer_env).map_err(StartupOutcomeError::from);
if let Err(err) = &token {
if err.to_string().contains("is empty") {
// env var exists but holds "" - surface a 'set the secret' setup message
}
} Prevention
- Treat empty secrets as missing: assert non-empty in launch scripts and CI before starting Codex
- Use set -u and :? parameter expansion in wrapper scripts
- Add a preflight that reads every bearer_token_env_var in config.toml and verifies presence and non-empty
- Prefer executor-owned token resolution for cloud-run servers so the local shell env cannot cause this
When it happens
Trigger: config.toml contains [mcp_servers.NAME] with streamable_http transport and bearer_token_env_var = "FOO_TOKEN", and the process launching Codex exports FOO_TOKEN as empty (FOO_TOKEN= codex, an .env line 'FOO_TOKEN=', a CI secret defined but unset, docker-compose '- FOO_TOKEN='). Hit only when the token is resolved host-side, i.e. the server runs in the local environment or the executor does not advertise http_header_env_vars.
Common situations: CI pipeline references a secret never configured on the runner; compose/direnv files with a trailing '=' and no value; a secret-name typo so the platform injects an empty placeholder; a login script that exports the variable before fetching the token.
Related errors
- Environment variable {env_var} for MCP server '{server_name}
- Environment variable {env_var} for MCP server '{server_name}
- executor-owned MCP server `{server_name}` cannot use hosted
- Invalid MCP server name '{server_name}': must match pattern
- non-local HTTP MCP server `{server_name}` did not resolve an
AI-assisted analysis of openai/codex@339751715c (2026-08-25).
Data as JSON: /api/errors/1059b5383f84c3d4.
Report an issue: GitHub.