openai/codex · error

failed to read synthetic bubblewrap mount marker {}: {err}

Error message

failed to read synthetic bubblewrap mount marker {}: {err}

What it means

When a synthetic target preserves a pre-existing path, registration checks whether another live process already owns a synthetic copy by reading every live PID's marker file (synthetic_mount_marker_dir_has_active_synthetic_owner, linux_run_main.rs:1033). NotFound maps to no-owner; any other read error panics: permission-denied on the marker file (ownership or permission drift inside the registry), EACCES on traversal, or genuine I/O errors from failing storage.

Source

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

            })
            .collect()
    })
}

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

fn synthetic_mount_marker_dir_has_active_synthetic_owner(marker_dir: &Path) -> bool {
    synthetic_mount_marker_dir_has_active_process_matching(marker_dir, |path| {
        match fs::read(path) {
            Ok(contents) => contents == SYNTHETIC_MOUNT_MARKER_SYNTHETIC,
            Err(err) if err.kind() == std::io::ErrorKind::NotFound => false,
            Err(err) => panic!(
                "failed to read synthetic bubblewrap mount marker {}: {err}",
                path.display()
            ),
        }
    })
}

fn synthetic_mount_marker_dir_has_active_process(marker_dir: &Path) -> bool {
    synthetic_mount_marker_dir_has_active_process_matching(marker_dir, |_| true)
}

fn synthetic_mount_marker_dir_has_active_process_matching(
    marker_dir: &Path,
    matches_marker: impl Fn(&Path) -> bool,
) -> bool {
    let entries = match fs::read_dir(marker_dir) {
        Ok(entries) => entries,
        Err(err) if err.kind() == std::io::ErrorKind::NotFound => return false,

View on GitHub (pinned to 339751715c)

Solutions

  1. Inspect the exact marker path in the panic with ls -l and restore access: chown $(id -u) plus chmod u+rw.
  2. With all codex processes stopped, reset the registry: rm -rf ${TMPDIR:-/tmp}/codex-bwrap-synthetic-mount-targets-$(id -u).
  3. Check dmesg for I/O errors if the permissions look correct.
  4. Report upstream if a freshly created registry reproduces the failure.

Example fix

# before: unreadable marker file blocks registration
ls -l /tmp/codex-bwrap-synthetic-mount-targets-1000/0123abcd4567/1234
# -r-------- 1 root root ...

# after: restore ownership and permissions, or reset the registry
chown -R $(id -u) /tmp/codex-bwrap-synthetic-mount-targets-$(id -u)
chmod -R u+rwX /tmp/codex-bwrap-synthetic-mount-targets-$(id -u)
Defensive patterns

Strategy: validation

Validate before calling

fn registry_files_readable() -> Result<(), std::path::PathBuf> {
    let root = std::env::temp_dir().join(format!(
        "codex-bwrap-synthetic-mount-targets-{}",
        unsafe { libc::geteuid() }
    ));
    for dir in std::fs::read_dir(&root).into_iter().flatten().flatten() {
        for entry in std::fs::read_dir(dir.path()).into_iter().flatten().flatten() {
            if std::fs::File::open(entry.path()).is_err() {
                return Err(entry.path());
            }
        }
    }
    Ok(())
}

Prevention

When it happens

Trigger: Registering a preserves-pre-existing-path target (an existing empty file or dir in the workspace) while the registry contains a marker file unreadable by the current effective uid — chmod or chown drift, state restored from backups, privilege-drop mixing — or storage returning EIO.

Common situations: Permission sweeps or manual chmod inside /tmp/codex-bwrap-synthetic-mount-targets-*; uid changes between sessions; backup or restore tooling dropping permissions; failing disks.

Related errors


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