{"record":{"id":"8c4ec276d1e99c51","repo":"firecracker-microvm/firecracker","slug":"vhostuserblock-does-not-support-snapshotting-yet-8c4ec2","errorCode":null,"errorMessage":"VhostUserBlock does not support snapshotting yet","messagePattern":"VhostUserBlock does not support snapshotting yet","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/vmm/src/devices/virtio/block/vhost_user/persist.rs","lineNumber":34,"sourceCode":"#[derive(Debug, Clone, Serialize, Deserialize)]\npub struct VhostUserBlockState {\n    id: String,\n    partuuid: Option<String>,\n    cache_type: CacheType,\n    root_device: bool,\n    socket_path: String,\n    vu_acked_protocol_features: u64,\n    config_space: Vec<u8>,\n    virtio_state: VirtioDeviceState,\n}\n\nimpl Persist<'_> for VhostUserBlock {\n    type State = VhostUserBlockState;\n    type ConstructorArgs = BlockConstructorArgs;\n    type Error = VhostUserBlockError;\n\n    fn save(&self) -> Self::State {\n        unimplemented!(\"VhostUserBlock does not support snapshotting yet\");\n    }\n\n    fn restore(\n        _constructor_args: Self::ConstructorArgs,\n        _state: &Self::State,\n    ) -> Result<Self, Self::Error> {\n        Err(VhostUserBlockError::SnapshottingNotSupported)\n    }\n}\n","sourceCodeStart":16,"sourceCodeEnd":44,"githubUrl":"https://github.com/firecracker-microvm/firecracker/blob/ea50487ec11602100b90ed63f85fe00bd30fbde8/src/vmm/src/devices/virtio/block/vhost_user/persist.rs#L16-L44","documentation":"The `Persist` impl for VhostUserBlock in src/vmm/src/devices/virtio/block/vhost_user/persist.rs makes the limitation explicit at both ends of the lifecycle: `save()` is an `unimplemented!()` panic (CreateSnapshot dies while serializing device state), and `restore()` returns `Err(VhostUserBlockError::SnapshottingNotSupported)`. So saving panics hard, while loading a VM that contained a vhost-user block fails with a typed error instead.","triggerScenarios":"CreateSnapshot on a microVM with a vhost-user block reaches `save()` and panics. Restore is reached when the VMM loads a snapshot whose state references a vhost-user block (restoring such legacy/future state files), producing VhostUserBlockError::SnapshottingNotSupported propagating out of the restore call as an error (not a panic).","commonSituations":"Same population as the prepare_save panic: out-of-process storage users (SPDK, custom vhost-user-blk backends) attempting snapshot/restore or live migration. The typed error additionally surfaces in tooling that inspects or replays snapshots, and in integration tests that exercise Persist::restore directly.","solutions":["Treat vhost-user block and snapshots as mutually exclusive today: switch the VM to virtio-block (path_on_host drive) for any microVM you intend to snapshot or restore.","If you hit the typed SnapshottingNotSupported on restore, the snapshot was produced by a configuration Firecracker cannot reconstruct — rebuild the VM config without the vhost-user block and re-create the snapshot.","At the orchestrator level, pre-check VM config for vhost-user block sockets before issuing CreateSnapshot/LoadSnapshot (see validation snippet).","Watch upstream Firecracker releases for vhost-user block snapshot support and pin your config until then."],"exampleFix":"# before\n# VM has a vhost-user block (socket: \"...\"), then:\ncurl --unix-socket fc.sock -X PUT http://localhost/snapshot/create -d '{\"snapshot_path\": \"vm.snap\", \"mem_file_path\": \"vm.mem\"}'\n# panic: VhostUserBlock does not support snapshotting yet / restore fails with SnapshottingNotSupported\n\n# after (virtio-block drive, snapshot-safe)\ncurl --unix-socket fc.sock -X PUT http://localhost/drives/rootfs -H 'Content-Type: application/json' -d '{\"drive_id\": \"rootfs\", \"path_on_host\": \"/vm/rootfs.ext4\", \"is_root_device\": true, \"is_read_only\": false}'\ncurl --unix-socket fc.sock -X PUT http://localhost/snapshot/create -H 'Content-Type: application/json' -d '{\"snapshot_path\": \"vm.snap\", \"mem_file_path\": \"vm.mem\"}'","handlingStrategy":"validation","validationCode":"// Mirror the Persist limitation: reject snapshot save/load for VMs with vhost-user blocks\n// before touching the Firecracker API.\nfn can_snapshot(cfg: &VmConfig) -> Result<(), VhostUserBlockError> {\n    if cfg.block_devices.iter().any(|d| d.is_vhost_user()) {\n        return Err(VhostUserBlockError::SnapshottingNotSupported);\n    }\n    Ok(())\n}\n\ncan_snapshot(&cfg)?; // fail fast with a typed, catchable error\napi.create_snapshot(req).await?;","typeGuard":"fn is_snapshot_capable(dev: &Block) -> bool {\n    matches!(dev, Block::Virtio(_)) // only virtio-block implements Persist for snapshots\n}","tryCatchPattern":"// save() panics (unimplemented!()), so only restore() is catchable:\nmatch VhostUserBlock::restore(args, &state) {\n    Ok(dev) => dev,\n    Err(VhostUserBlockError::SnapshottingNotSupported) => {\n        // rebuild the VM with virtio-block instead of retrying restore\n        return rebuild_with_virtio_block(args);\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Keep vhost-user-backed VMs out of any snapshot/restore pipeline; enforce it in the orchestrator's config admission.","On restore failure, treat SnapshottingNotSupported as a permanent config mismatch — recreate the VM config rather than retrying.","Cover save and restore paths in integration tests per device backend so unsupported combos surface early.","Monitor firecracker logs for 'not implemented' panics after snapshot calls; they indicate this exact gap."],"tags":["rust","firecracker","vhost-user","snapshot","restore","persistence"],"backgroundTag":null,"analyzedSha":"ea50487ec11602100b90ed63f85fe00bd30fbde8","analyzedAt":"2026-08-16T11:52:35.093Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}