{"record":{"id":"e7fe63c5b518b10a","repo":"firecracker-microvm/firecracker","slug":"device-is-not-initialized","errorCode":null,"errorMessage":"Device is not initialized","messagePattern":"Device is not initialized","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/vmm/src/devices/virtio/vsock/device.rs","lineNumber":139,"sourceCode":"        Self::with_queues(cid, backend, queues)\n    }\n\n    /// Retrieve the cid associated with this vsock device.\n    pub fn cid(&self) -> u64 {\n        self.cid\n    }\n\n    /// Access the backend behind the device.\n    pub fn backend(&self) -> &B {\n        &self.backend\n    }\n\n    /// Signal the guest driver that we've used some virtio buffers that it had previously made\n    /// available.\n    pub fn signal_used_queue(&self, qidx: usize) -> Result<(), DeviceError> {\n        self.device_state\n            .active_state()\n            .expect(\"Device is not initialized\")\n            .interrupt\n            .trigger(VirtioInterruptType::Queue(qidx.try_into().unwrap_or_else(\n                |_| panic!(\"vsock: invalid queue index: {qidx}\"),\n            )))\n            .map_err(DeviceError::FailedSignalingIrq)\n    }\n\n    /// Signal the guest which queues are ready to be consumed\n    pub fn signal_used_queues(&self, used_queues: &[u16]) -> Result<(), DeviceError> {\n        self.device_state\n            .active_state()\n            .expect(\"Device is not initialized\")\n            .interrupt\n            .trigger_queues(used_queues)\n            .map_err(DeviceError::FailedSignalingIrq)\n    }\n\n    /// Walk the driver-provided RX queue buffers and attempt to fill them up with any data that we","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/firecracker-microvm/firecracker/blob/81b38b9dad6056d7a48073e95ac5a9aed51cb2ab/src/vmm/src/devices/virtio/vsock/device.rs#L121-L157","documentation":"Panic from `expect(\"Device is not initialized\")` in `Vsock::signal_used_queue` (src/vmm/src/devices/virtio/vsock/device.rs:141). `self.device_state.active_state()` returns `Some` only after the guest virtio driver has activated the device ( FEATURES_OK/DRIVER_OK handshake completed and the device moved to Activated). If any code path signals the used queue before activation, `active_state()` is None and the process aborts.","triggerScenarios":"Calling `signal_used_queue(qidx)` (or the backend doing so indirectly) before the guest driver finished the virtio activation handshake: e.g. a host-side vsock peer connects and pushes data while the device is still in `Inactive`/`Created` state, or during snapshot-restore before `activate()` has run.","commonSituations":"Guest boots a kernel without a virtio-vsock driver (device never activates) while the host backend already delivers RX data; restoring from a snapshot where the backend/event handler threads start before the device is re-activated; tests that instantiate the device and drive queues directly without an activate step.","solutions":["Make sure the vsock backend event handler is only registered/started after the device receives DRIVER_OK (check `device_state.active_state().is_some()` before signaling)","If restoring from a snapshot, verify the restore path calls `activate()` on the vsock device before resuming queue/event processing","In library code, replace the `expect` with a graceful branch: `match self.device_state.active_state() { Some(s) => s.interrupt.trigger(..), None => { warn!(...); Ok(()) } }`","If you drive the device from tests, activate it with a mock interrupt/queue pair first"],"exampleFix":"// before\nself.device_state\n    .active_state()\n    .expect(\"Device is not initialized\")\n    .interrupt\n    .trigger(VirtioInterruptType::Queue(qidx.try_into().unwrap_or_else(|_| panic!(\"vsock: invalid queue index: {qidx}\"))))\n    .map_err(DeviceError::FailedSignalingIrq)\n\n// after\nif let Some(state) = self.device_state.active_state() {\n    state.interrupt\n        .trigger(VirtioInterruptType::Queue(qidx as u16))\n        .map_err(DeviceError::FailedSignalingIrq)\n} else {\n    warn!(\"vsock: signal_used_queue before activation (qidx {qidx})\");\n    Ok(())\n}","handlingStrategy":"validation","validationCode":"// Only let the backend notify queues once the guest driver activated the device\nif vsock.device_state().active_state().is_some() {\n    vsock.signal_used_queue(qidx)?;\n} else {\n    warn!(\"vsock not activated; deferring queue signal\");\n}","typeGuard":"fn is_vsock_activated(dev: &Vsock<impl VsockBackend>) -> bool {\n    dev.device_state().active_state().is_some()\n}","tryCatchPattern":"// Panics cannot be caught with Result; as a last resort isolate third-party threads:\nlet r = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| vsock.signal_used_queue(0)));\nif r.is_err() { /* device not initialized or irq failure: restart device */ }","preventionTips":["Start vsock backend event processing only after the virtio DRIVER_OK activation handshake","On snapshot restore, call activate() before re-registering queue event fds","Confirm the guest kernel actually loads a virtio-vsock driver before relying on host->guest pushes"],"tags":["rust","panic","virtio","vsock","device-state","firecracker"],"backgroundTag":"virtio-device-not-activated","analyzedSha":"81b38b9dad6056d7a48073e95ac5a9aed51cb2ab","analyzedAt":"2026-08-19T05:27:02.517Z","contentChangedAt":"2026-08-19T05:27:02.517Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}