firecracker-microvm/firecracker · critical

VhostUserBlock does not support snapshotting yet

Error message

VhostUserBlock does not support snapshotting yet

What it means

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.

Source

Thrown at src/vmm/src/devices/virtio/block/vhost_user/persist.rs:34

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VhostUserBlockState {
    id: String,
    partuuid: Option<String>,
    cache_type: CacheType,
    root_device: bool,
    socket_path: String,
    vu_acked_protocol_features: u64,
    config_space: Vec<u8>,
    virtio_state: VirtioDeviceState,
}

impl Persist<'_> for VhostUserBlock {
    type State = VhostUserBlockState;
    type ConstructorArgs = BlockConstructorArgs;
    type Error = VhostUserBlockError;

    fn save(&self) -> Self::State {
        unimplemented!("VhostUserBlock does not support snapshotting yet");
    }

    fn restore(
        _constructor_args: Self::ConstructorArgs,
        _state: &Self::State,
    ) -> Result<Self, Self::Error> {
        Err(VhostUserBlockError::SnapshottingNotSupported)
    }
}

View on GitHub (pinned to ea50487ec1)

Solutions

  1. 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.
  2. 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.
  3. At the orchestrator level, pre-check VM config for vhost-user block sockets before issuing CreateSnapshot/LoadSnapshot (see validation snippet).
  4. Watch upstream Firecracker releases for vhost-user block snapshot support and pin your config until then.

Example fix

# before
# VM has a vhost-user block (socket: "..."), then:
curl --unix-socket fc.sock -X PUT http://localhost/snapshot/create -d '{"snapshot_path": "vm.snap", "mem_file_path": "vm.mem"}'
# panic: VhostUserBlock does not support snapshotting yet / restore fails with SnapshottingNotSupported

# after (virtio-block drive, snapshot-safe)
curl --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}'
curl --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"}'
Defensive patterns

Strategy: validation

Validate before calling

// Mirror the Persist limitation: reject snapshot save/load for VMs with vhost-user blocks
// before touching the Firecracker API.
fn can_snapshot(cfg: &VmConfig) -> Result<(), VhostUserBlockError> {
    if cfg.block_devices.iter().any(|d| d.is_vhost_user()) {
        return Err(VhostUserBlockError::SnapshottingNotSupported);
    }
    Ok(())
}

can_snapshot(&cfg)?; // fail fast with a typed, catchable error
api.create_snapshot(req).await?;

Type guard

fn is_snapshot_capable(dev: &Block) -> bool {
    matches!(dev, Block::Virtio(_)) // only virtio-block implements Persist for snapshots
}

Try / catch

// save() panics (unimplemented!()), so only restore() is catchable:
match VhostUserBlock::restore(args, &state) {
    Ok(dev) => dev,
    Err(VhostUserBlockError::SnapshottingNotSupported) => {
        // rebuild the VM with virtio-block instead of retrying restore
        return rebuild_with_virtio_block(args);
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of firecracker-microvm/firecracker@ea50487ec1 (2026-08-16). Data as JSON: /api/errors/8c4ec276d1e99c51. Report an issue: GitHub.