openai/codex · error · anyhow::Error
missing required environment variable {env_var}
Error message
missing required environment variable {env_var} What it means
When a hook injects a header via secret_env_var, compile_injected_header resolves the variable immediately at hook-compile time (proxy startup) through env::var. If the variable is unset, compilation fails with 'missing required environment variable {env_var}', wrapped in the context 'failed to compile injected header {name}'. Secrets are read once at startup, never per request.
Source
Thrown at codex-rs/network-proxy/src/mitm_hook.rs:358
}
fn compile_injected_header<EnvFn, FileFn>(
header: &InjectedHeaderConfig,
resolve_env_var: &EnvFn,
read_secret_file: &FileFn,
) -> Result<ResolvedInjectedHeader>
where
EnvFn: Fn(&str) -> Option<String>,
FileFn: Fn(&AbsolutePathBuf) -> Result<String>,
{
let name = parse_header_name(&header.name)?;
let (secret, source) = match (
header.secret_env_var.as_deref(),
header.secret_file.as_deref(),
) {
(Some(env_var), None) => {
let value = resolve_env_var(env_var)
.ok_or_else(|| anyhow!("missing required environment variable {env_var}"))?;
(value, SecretSource::EnvVar(env_var.to_string()))
}
(None, Some(secret_file)) => {
let path = parse_secret_file(secret_file)?;
let value = read_secret_file(&path)?;
(value, SecretSource::File(path))
}
_ => {
return Err(anyhow!(
"expected exactly one of secret_env_var or secret_file"
));
}
};
let prefix = header.prefix.clone().unwrap_or_default();
let value = HeaderValue::from_str(&format!("{prefix}{secret}"))
.with_context(|| format!("invalid value for injected header {}", header.name))?;
View on GitHub (pinned to 339751715c)
Solutions
- Export the variable in the exact environment that starts the network proxy (shell profile, systemd Environment=, or the launcher's env)
- Verify presence without printing the value: test -n "$MY_TOKEN" && echo set
- If the process cannot see environment variables, switch the entry to secret_file with an absolute path to a readable secret file
- Check the spelling in secret_env_var character-for-character against the environment
Example fix
# before — header needs MY_TOKEN but the service env lacks it [[network.mitm_hooks.actions.inject_request_headers]] name = "authorization" secret_env_var = "MY_TOKEN" prefix = "Bearer " # after — read from an absolute-path file the service can access [[network.mitm_hooks.actions.inject_request_headers]] name = "authorization" secret_file = "/etc/codex/secrets/my_token" prefix = "Bearer "
Defensive patterns
Strategy: validation
Validate before calling
// Rust — check env secrets before starting the proxy
for hook in &config.mitm_hooks {
for h in &hook.actions.inject_request_headers {
if let Some(name) = &h.secret_env_var {
std::env::var(name)
.map_err(|_| anyhow!("{name} is not set in the proxy environment"))?;
}
}
} Type guard
fn env_secret_available(h: &InjectedHeaderConfig) -> bool {
match (&h.secret_env_var, &h.secret_file) {
(Some(name), None) => std::env::var(name).is_ok(),
(None, Some(_)) => true,
_ => false,
}
} Try / catch
match compile_mitm_hooks(&config) {
Ok(hooks) => { /* proceed */ }
Err(err) => eprintln!("hook compilation failed: {err:#}"), // 'failed to compile injected header authorization: missing required environment variable MY_TOKEN'
} Prevention
- Pre-flight every secret_env_var with std::env::var before spawning the proxy
- For services/daemons prefer secret_file with an absolute path over env vars
- Verify presence with test -n "$VAR" — never echo the value into logs
- Use the same launch path in CI and production so env parity is real
When it happens
Trigger: An inject_request_headers entry like { name = "authorization", secret_env_var = "MY_TOKEN" } compiled by compile_mitm_hooks while MY_TOKEN is absent from the proxy process's environment — typical when the proxy is spawned by systemd, a daemon manager, or a different shell than the one where the variable was exported.
Common situations: Variable exported interactively but the proxy runs as a service; CI secrets not passed into the job env; typo in the variable name; renaming the var in config but not in the launch environment.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- expected exactly one of secret_env_var or secret_file
- network.mitm_hooks[{hook_index}].match.body is reserved for
- network.mitm_hooks[{hook_index}].host must not be empty
- path_prefixes must not contain empty entries
- glob pattern must not be empty
AI-assisted analysis of openai/codex@339751715c (2026-08-25).
Data as JSON: /api/errors/46a932b73abf0d7d.
Report an issue: GitHub.