openai/codex · error

failed to register protected create target {}: {err}

Error message

failed to register protected create target {}: {err}

What it means

register_protected_create_targets writes a per-PID marker file containing PROTECTED_CREATE_MARKER so concurrent processes can tell who owns a protected-create registration and cleanup can distinguish owners. fs::write panics on storage failures after the directory was just created: ENOSPC, EDQUOT, EIO, or the marker dir vanishing between create and write despite the cross-process flock.

Source

Thrown at codex-rs/linux-sandbox/src/linux_run_main.rs:1010

}

fn register_protected_create_targets(
    targets: &[crate::bwrap::ProtectedCreateTarget],
) -> Vec<ProtectedCreateTargetRegistration> {
    with_synthetic_mount_registry_lock(|| {
        targets
            .iter()
            .map(|target| {
                let marker_dir = synthetic_mount_marker_dir(target.path());
                fs::create_dir_all(&marker_dir).unwrap_or_else(|err| {
                    panic!(
                        "failed to create protected create marker directory {}: {err}",
                        marker_dir.display()
                    )
                });
                let marker_file = marker_dir.join(std::process::id().to_string());
                fs::write(&marker_file, PROTECTED_CREATE_MARKER).unwrap_or_else(|err| {
                    panic!(
                        "failed to register protected create target {}: {err}",
                        target.path().display()
                    )
                });
                ProtectedCreateTargetRegistration {
                    target: target.clone(),
                    marker_file,
                    marker_dir,
                }
            })
            .collect()
    })
}

fn synthetic_mount_marker_contents(target: &crate::bwrap::SyntheticMountTarget) -> &'static [u8] {
    if target.preserves_pre_existing_path() {
        SYNTHETIC_MOUNT_MARKER_EXISTING
    } else {

View on GitHub (pinned to 339751715c)

Solutions

  1. Free or enlarge the filesystem backing TMPDIR, then retry the command.
  2. Verify the marker dir path from the panic still exists and is writable.
  3. Check dmesg and SMART for I/O errors when space is fine.
  4. Clear the registry with all sessions stopped if the state looks damaged.

Example fix

# before: /tmp tmpfs sized too small for parallel protected-create runs
mount -t tmpfs -o size=256m tmpfs /tmp

# after: adequate headroom
mount -t tmpfs -o size=2g tmpfs /tmp
Defensive patterns

Strategy: validation

Validate before calling

fn temp_free_bytes(min: u64) -> bool {
    let dir = std::env::temp_dir().canonicalize().unwrap_or_default();
    let c = std::ffi::CString::new(dir.as_os_str().as_encoded_bytes()).unwrap_or_default();
    let mut st: libc::statvfs = unsafe { std::mem::zeroed() };
    unsafe { libc::statvfs(c.as_ptr(), &mut st) } == 0 && (st.f_bavail as u64) * (st.f_bsize as u64) >= min
}

Prevention

When it happens

Trigger: Sandboxed runs with protected-create targets whose temp filesystem fills (sized tmpfs) or errors during run setup, right after the marker directory was created.

Common situations: Parallel sessions exhausting tmpfs; disk-full runners; failing storage; quota limits hit mid-write.

Related errors


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