{"record":{"id":"bee88d39894479bc","repo":"wasmerio/wasmer","slug":"journal-restore-error-failed-renumber-file-descri-bee88d","errorCode":null,"errorMessage":"journal restore error: failed renumber file descriptor after duplicate (from={}, to={}) - {}","messagePattern":"journal restore error: failed renumber file descriptor after duplicate \\(from=(.+?), to=(.+?)\\) - (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/wasix/src/journal/effector/syscalls/fd_duplicate.rs","lineNumber":35,"sourceCode":"        )\n    }\n\n    pub fn apply_fd_duplicate(\n        ctx: &mut FunctionEnvMut<'_, WasiEnv>,\n        original_fd: Fd,\n        copied_fd: Fd,\n        cloexec: bool,\n    ) -> anyhow::Result<()> {\n        let ret_fd = crate::syscalls::fd_dup_internal(ctx, original_fd, 0, cloexec)\n            .map_err(|err| {\n                anyhow::format_err!(\n                    \"journal restore error: failed to duplicate file descriptor (original={original_fd}, copied={copied_fd}) - {err}\")\n            })?;\n\n        if ret_fd != copied_fd {\n            let ret = crate::syscalls::fd_renumber_internal(ctx, ret_fd, copied_fd);\n            if !matches!(ret, Ok(Errno::Success)) {\n                bail!(\n                    \"journal restore error: failed renumber file descriptor after duplicate (from={}, to={}) - {}\",\n                    ret_fd,\n                    copied_fd,\n                    ret.unwrap_or(Errno::Unknown)\n                );\n            }\n        }\n\n        Ok(())\n    }\n}\n","sourceCodeStart":17,"sourceCodeEnd":47,"githubUrl":"https://github.com/wasmerio/wasmer/blob/8c4b9ee9d33fb2068863fbb3d328683e7e6ff7f5/lib/wasix/src/journal/effector/syscalls/fd_duplicate.rs#L17-L47","documentation":"apply_fd_duplicate duplicates a descriptor during journal replay; if the duplicated fd doesn't land on the number recorded in the journal (ret_fd != copied_fd), it renumbers and that fd_renumber_internal call failed. The restored fd table then cannot match the snapshotted layout, so restore aborts.","triggerScenarios":"Journal restore replaying an FdDuplicate entry when fd_renumber_internal fails to move the fresh duplicate to the expected copied_fd (target fd invalid or occupied).","commonSituations":"Snapshot fd tables that conflict with fds allocated during restore; corrupted journals; version mismatch between the runtime that produced the journal and the restoring runtime.","solutions":["Take a fresh snapshot and restore from it.","Check for fd number conflicts in the restoring environment.","Use matching wasmer/wasix versions for snapshot creation and restore.","Validate journal integrity (no truncation or out-of-order entries)."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Ensure no restore-time allocations will collide with journal fd numbers\nlet journal_fds: std::collections::HashSet<u32> = journal.expected_fds().into_iter().collect();\nif journal_fds.iter().any(|fd| env.fd_in_use(*fd)) {\n    return Err(anyhow::anyhow!(\"fd table conflicts with journal; restore into a clean env\"));\n}","typeGuard":null,"tryCatchPattern":"match restore_from_journal(&env, &journal) {\n    Err(e) if e.to_string().contains(\"after duplicate\") => {\n        eprintln!(\"fd renumber after dup failed: {e}\");\n        resume_with_fresh_snapshot()?;\n    }\n    other => other?,\n}","preventionTips":["Restore into a pristine environment so journal fd numbers are free.","Keep snapshot/restore runtime versions in lockstep.","Verify journal completeness before replay."],"tags":["wasix","journal","fd-duplicate","snapshot-restore"],"backgroundTag":"journal-restore-failed","analyzedSha":"8c4b9ee9d33fb2068863fbb3d328683e7e6ff7f5","analyzedAt":"2026-09-01T23:06:31.009Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}