wasmerio/wasmer · error
journal restore error: failed to close descriptor (fd={fd})
Error message
journal restore error: failed to close descriptor (fd={fd}) - {} What it means
apply_fd_close replays an FdClose journal entry; the close outcome reports that the descriptor was not actually removed from the fd table (outcome.removed == false), so restore cannot reproduce the snapshotted state. The error is raised with Errno::Badf to indicate a bad/unknown descriptor.
Source
Thrown at lib/wasix/src/journal/effector/syscalls/fd_close.rs:19
use super::*;
use crate::syscalls::flush_captured_handle;
impl JournalEffector {
pub fn save_fd_close(ctx: &mut FunctionEnvMut<'_, WasiEnv>, fd: Fd) -> anyhow::Result<()> {
Self::save_event(ctx, JournalEntry::CloseFileDescriptorV1 { fd })
}
pub fn apply_fd_close(ctx: &mut FunctionEnvMut<'_, WasiEnv>, fd: Fd) -> anyhow::Result<()> {
let env = ctx.data();
let (_, state) = unsafe { env.get_memory_and_wasi_state(&ctx, 0) };
let outcome = state.fs.close_fd_and_capture_flush(fd);
if outcome.skipped_preopen {
return Ok(());
}
if !outcome.removed {
bail!(
"journal restore error: failed to close descriptor (fd={fd}) - {}",
Errno::Badf
);
}
flush_captured_handle(env, outcome.flush_target).map_err(|err| {
anyhow::anyhow!(
"journal restore error: failed to flush before closing descriptor (fd={fd}) - {err:?}"
)
})?;
Ok(())
}
}
View on GitHub (pinned to 8c4b9ee9d3)
Solutions
- Regenerate the snapshot/journal and restore from the new one.
- Check that preopen configuration (stdin/stdout/stderr/mounted dirs) matches the environment used when the journal was captured.
- Confirm the same wasix version is used for capture and restore.
- Verify the journal isn't being replayed twice or out of order.
Defensive patterns
Strategy: try-catch
Validate before calling
// Verify preopen layout matches before restore
if env.preopen_fds() != journal.initial_preopen_fds() {
return Err(anyhow::anyhow!("preopen fd layout differs from snapshot; align --mapdir/stdio flags"));
} Try / catch
match restore_from_journal(&env, &journal) {
Err(e) if e.to_string().contains("failed to close descriptor") => {
eprintln!("fd already closed/absent during restore: {e}; continuing with fresh snapshot");
resume_with_fresh_snapshot()?;
}
other => other?,
} Prevention
- Match preopen configuration (mapdirs, stdio) between capture and restore.
- Never replay a journal twice over the same environment.
- Retake snapshots when switching runtime versions.
When it happens
Trigger: Journal restore attempting to close an fd that no longer exists or is a preopen that cannot be removed (skipped_preopen path excluded), i.e. fd_close_internal did not remove the descriptor.
Common situations: Restoring journals against an environment whose preopened fds differ from the snapshot; duplicate close entries; runtime drift between snapshot and restore versions.
Related errors
- journal restore error: failed to set clock time (clock_id={c
- journal restore error: failed renumber file descriptor after
- journal restore error: failed renumber file descriptor after
- journal restore error: failed to renumber descriptor (from={
- journal restore error: failed to open descriptor (fd={fd}, p
AI-assisted analysis of wasmerio/wasmer@8c4b9ee9d3 (2026-09-01).
Data as JSON: /api/errors/6094a8b37ba917b1.
Report an issue: GitHub.