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
- Set CODEX_BWRAP_SHA256 to exactly the 64 hex characters of the bwrap digest (no sha256: prefix, no quotes, no whitespace) and rebuild.
- Leave the variable unset to disable digest verification entirely (typical for dev builds).
- 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
- Gate packaging on the digest format so bad builds fail at build time, not at first sandbox launch.
- The panic is lazy (OnceLock): run one sandboxed command in smoke tests to force expected_sha256() evaluation.
- Prefer unset over empty when verification is not wanted.
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
- failed to open bundled bubblewrap {}: {err}
- invalid bundled bubblewrap fd path: {err}
- failed to exec bundled bubblewrap {} via {fd_path}: {err}
- failed to normalize bundled bubblewrap path {}: {err}
- failed to read fd flags for preserved bubblewrap file descri
AI-assisted analysis of openai/codex@339751715c (2026-08-25).
Data as JSON: /api/errors/447ee8315cb2680c.
Report an issue: GitHub.