wasmerio/wasmer · error

journal restore error: failed to open descriptor (fd={fd}, p

Error message

journal restore error: failed to open descriptor (fd={fd}, path={path}) - {err}

What it means

apply_path_open replays a PathOpen journal entry by re-opening the recorded path at the expected fd; if the internal open returns an error, this bail fires with the fd and path. The restored process would otherwise be missing a file descriptor that existed in the snapshot.

Source

Thrown at lib/wasix/src/journal/effector/syscalls/path_open.rs:61

        fs_flags: Fdflags,
        fd_flags: Fdflagsext,
    ) -> anyhow::Result<()> {
        let res = crate::syscalls::path_open_internal(
            ctx.data(),
            dirfd,
            dirflags,
            path,
            o_flags,
            fs_rights_base,
            fs_rights_inheriting,
            fs_flags,
            fd_flags,
            Some(fd),
        );
        match res? {
            Ok(fd) => fd,
            Err(err) => {
                bail!(
                    "journal restore error: failed to open descriptor (fd={fd}, path={path}) - {err}"
                );
            }
        };
        Ok(())
    }
}

View on GitHub (pinned to 8c4b9ee9d3)

Solutions

  1. Ensure the file at `path` exists in the restored environment (restore the volume/workdir contents).
  2. Verify the base directory preopen and its rights (read/write) match the snapshot environment.
  3. Check path casing/symlinks differences between capture and restore hosts.
  4. Retake the snapshot in an environment matching the restore target.

Example fix

// before: restoring without mounting the volume that held /data/file.txt
// -> journal restore error: failed to open descriptor

// after: mount the same volume / preopen before resuming
// wasmer run app.wasm --mapdir /data:/host/data  (matching the snapshot layout)
Defensive patterns

Strategy: validation

Validate before calling

// Before restore, confirm every PathOpen target exists and is accessible
for op in journal.path_open_entries() {
    let p = env.resolve_preopen_path(op.base_fd, &op.path)
        .ok_or_else(|| anyhow::anyhow!("no preopen for base fd {} during restore", op.base_fd))?;
    if !std::path::Path::new(&p).exists() {
        return Err(anyhow::anyhow!("restore needs file '{}' which is missing", p));
    }
}

Type guard

fn is_openable(p: &std::path::Path) -> bool {
    use std::os::unix::fs::PermissionsExt;
    std::fs::metadata(p).map(|m| !m.is_dir()).unwrap_or(false)
}

Try / catch

match restore_from_journal(&env, &journal) {
    Err(e) if e.to_string().contains("failed to open descriptor") => {
        eprintln!("missing file during restore: {e}; remount volumes and retry");
        remount_volumes_and_retry()?;
    }
    other => other?,
}

Prevention

When it happens

Trigger: Journal restore applying PathOpen when path_open_internal fails: file missing on the restored filesystem, wrong base dir fd, permission/capability (Notcapable) issues, or the preopen for the path is absent.

Common situations: Snapshot taken on a machine/container whose mounted volumes or working directory contents differ from the restore target; missing read/write rights on the preopened directory; relative paths no longer resolvable after restore.

Related errors


AI-assisted analysis of wasmerio/wasmer@8c4b9ee9d3 (2026-09-01). Data as JSON: /api/errors/16495828d3120046. Report an issue: GitHub.