openai/codex · critical

invalid CODEX_BWRAP_SHA256 value: {err}

Error message

invalid CODEX_BWRAP_SHA256 value: {err}

What it means

The build pipeline can embed an expected SHA-256 for the bundled bwrap via the compile-time CODEX_BWRAP_SHA256 env var (option_env!). On first sandbox use, expected_sha256() parses that baked-in string and panics unless it is exactly 64 hex characters; an all-zero digest disables verification. This is a build-configuration defect compiled into the binary, evaluated lazily through a OnceLock at first sandbox launch.

Source

Thrown at codex-rs/linux-sandbox/src/bundled_bwrap.rs:123

    if let Some(path) = bazel_bwrap::candidate() {
        candidates.push(path);
    }
    candidates
}

fn is_executable_file(path: &Path) -> bool {
    let Ok(metadata) = path.metadata() else {
        return false;
    };
    metadata.is_file() && metadata.permissions().mode() & 0o111 != 0
}

fn expected_sha256() -> Option<[u8; 32]> {
    static EXPECTED: OnceLock<Option<[u8; 32]>> = OnceLock::new();
    *EXPECTED.get_or_init(|| {
        let raw_digest = option_env!("CODEX_BWRAP_SHA256")?;
        let digest = parse_sha256_hex(raw_digest)
            .unwrap_or_else(|err| panic!("invalid CODEX_BWRAP_SHA256 value: {err}"));
        (digest != NULL_SHA256_DIGEST).then_some(digest)
    })
}

fn verify_digest(file: &File, expected: Option<[u8; 32]>, path: &Path) -> Result<(), String> {
    let Some(expected) = expected else {
        return Ok(());
    };

    let mut file = file
        .try_clone()
        .map_err(|err| format!("failed to clone bundled bubblewrap fd: {err}"))?;
    let mut hasher = Sha256::new();
    let mut buffer = [0_u8; 8192];
    loop {
        let read = file.read(&mut buffer).map_err(|err| {
            format!(
                "failed to read bundled bubblewrap {} for digest verification: {err}",

View on GitHub (pinned to 339751715c)

Solutions

  1. Set CODEX_BWRAP_SHA256 to exactly the 64 hex characters of the bwrap digest (no sha256: prefix, no quotes, no whitespace) and rebuild.
  2. Leave the variable unset to disable digest verification entirely (typical for dev builds).
  3. Add a build.rs or CI assertion that the value matches ^[0-9a-fA-F]{64}$ before packaging.

Example fix

# before
export CODEX_BWRAP_SHA256='sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08'

# after
export CODEX_BWRAP_SHA256=9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
Defensive patterns

Strategy: validation

Validate before calling

# CI gate before building or packaging
if [ -n "$CODEX_BWRAP_SHA256" ] && ! echo "$CODEX_BWRAP_SHA256" | grep -qE '^[0-9a-fA-F]{64}$'; then
  echo "CODEX_BWRAP_SHA256 must be exactly 64 hex characters" >&2
  exit 1
fi

Prevention

When it happens

Trigger: Building the linux-sandbox crate with CODEX_BWRAP_SHA256 set to a malformed value: wrong length (truncated copy-paste), a sha256: prefix left on, surrounding quotes or whitespace, or non-hex characters. The panic then hits the first time a sandboxed command runs, not at process startup.

Common situations: Release/packaging pipelines passing a prefixed or quoted digest; developers exporting the variable manually with a typo; CI that never launches the sandbox, so the bad value ships unnoticed.

Related errors


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