openai/codex · error

failed to create protected create marker directory {}: {err}

Error message

failed to create protected create marker directory {}: {err}

What it means

register_protected_create_targets (linux_run_main.rs:994) uses the same per-uid hash registry for paths the sandbox must never let the workload create (protected workspace metadata): it creates the marker directory under the flock before forking. create_dir_all panics when ${TMPDIR}/codex-bwrap-synthetic-mount-targets-<euid> is not creatable: unwritable or read-only TMPDIR, ENOSPC, or a non-directory ancestor.

Source

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

                    target,
                    marker_file,
                    marker_dir,
                }
            })
            .collect()
    })
}

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()

View on GitHub (pinned to 339751715c)

Solutions

  1. Set TMPDIR to a writable directory with free space and rerun.
  2. Fix permissions on the deepest existing ancestor of the path printed in the panic.
  3. Enlarge or free the filesystem backing TMPDIR.
  4. Reset the stale registry root with all codex processes stopped.

Example fix

# before: TMPDIR inside a read-only mount
TMPDIR=/srv/locked-tmp codex ...

# after: writable temp root
TMPDIR=/var/tmp/codex codex ...
Defensive patterns

Strategy: validation

Validate before calling

fn temp_registry_writable() -> std::io::Result<()> {
    let root = std::env::temp_dir().canonicalize()?;
    let probe = root.join(format!("codex-probe-{}", std::process::id()));
    std::fs::create_dir_all(&probe)?;
    std::fs::write(probe.join("p"), b"x")?;
    std::fs::remove_dir_all(&probe)?;
    Ok(())
}

Prevention

When it happens

Trigger: Any sandboxed run that carries protected_create_targets (also the only case that creates the exec-start pipe, linux_run_main.rs:579) while the temp root is read-only, permission-denied, or full.

Common situations: Read-only /tmp hardening; TMPDIR misconfiguration in service units; PrivateTmp with restrictive mount flags; tmpfs exhaustion.

Related errors


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