{"record":{"id":"a70053a394843558","repo":"firecracker-microvm/firecracker","slug":"error-receiving-api-request","errorCode":null,"errorMessage":"Error receiving API request.","messagePattern":"Error receiving API request\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/firecracker/src/api_server_adapter.rs","lineNumber":112,"sourceCode":"    }\n\n    fn handle_request(&mut self, event_manager: &mut EventManager) {\n        if let Some(api_request) = self.request.take() {\n            let request_is_pause = *api_request == VmmAction::Pause;\n            self._handle_request(*api_request, event_manager);\n\n            // If the latest req is a pause request, temporarily switch to a mode where we\n            // do blocking `recv`s on the `from_api` receiver in a loop, until we get\n            // unpaused. The device emulation is implicitly paused since we do not\n            // return to `run_microvm` and hence `event_manager.run()` is not called\n            // again: device fds (virtqueue notifications, tap, rate limiters, timers)\n            // are not polled until we break out of this loop on `Resume`.\n            if request_is_pause {\n                // This loop only attempts to process API requests, so things like the\n                // metric flush timerfd handling are frozen as well (an explicit `FlushMetrics`\n                // request still goes through).\n                loop {\n                    let req = self.from_api.recv().expect(\"Error receiving API request.\");\n                    let req_is_resume = *req == VmmAction::Resume;\n                    self._handle_request(*req, event_manager);\n                    if req_is_resume {\n                        break;\n                    }\n                }\n            }\n        }\n    }\n}\nimpl MutEventSubscriber for ApiServerAdapter {\n    /// Handle a read event (EPOLLIN).\n    fn process(&mut self, event: Events, _: &mut EventOps) {\n        let source = event.fd();\n        let event_set = event.event_set();\n\n        if source == self.api_event_fd.as_raw_fd() && event_set == EventSet::IN {\n            let _ = self.api_event_fd.read();","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/firecracker-microvm/firecracker/blob/23b09b943fa3cd4a04004fe55724f0b5c2410f45/src/firecracker/src/api_server_adapter.rs#L94-L130","documentation":"After a Pause request, ApiServerAdapter::handle_request blocks in a loop on the mpsc channel from the API thread, waiting for a Resume (or other API request). The panic fires when from_api.recv() returns Err, meaning the channel's sending half (held by the API server thread) was dropped — i.e. the API thread has terminated or disconnected — so no further requests can ever be received and the VMM would deadlock waiting for Resume. It is raised at src/firecracker/src/api_server_adapter.rs:112 inside the post-pause blocking recv loop.","triggerScenarios":"Thrown at src/firecracker/src/api_server_adapter.rs:110 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Check the API socket and event loop for errors that break request reception (closed fd, epoll error).","Verify the API thread did not exit or panic before the request arrived."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"23b09b943fa3cd4a04004fe55724f0b5c2410f45","analyzedAt":"2026-09-19T00:01:22.326Z","contentChangedAt":"2026-09-19T00:01:22.326Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}