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

  1. Export the variable in the exact environment that starts the network proxy (shell profile, systemd Environment=, or the launcher's env)
  2. Verify presence without printing the value: test -n "$MY_TOKEN" && echo set
  3. If the process cannot see environment variables, switch the entry to secret_file with an absolute path to a readable secret file
  4. 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

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


AI-assisted analysis of openai/codex@339751715c (2026-08-25). Data as JSON: /api/errors/46a932b73abf0d7d. Report an issue: GitHub.