firecracker-microvm/firecracker · error

Error receiving API request.

Error message

Error receiving API request.

What it means

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.

Solutions

  1. Check the API socket and event loop for errors that break request reception (closed fd, epoll error).
  2. Verify the API thread did not exit or panic before the request arrived.
Defensive patterns

Strategy: try-catch

When it happens

Trigger: Thrown at src/firecracker/src/api_server_adapter.rs:110 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of firecracker-microvm/firecracker@23b09b943f (2026-09-19). Data as JSON: /api/errors/a70053a394843558. Report an issue: GitHub.

Appendix: source

Thrown at src/firecracker/src/api_server_adapter.rs:112

    }

    fn handle_request(&mut self, event_manager: &mut EventManager) {
        if let Some(api_request) = self.request.take() {
            let request_is_pause = *api_request == VmmAction::Pause;
            self._handle_request(*api_request, event_manager);

            // If the latest req is a pause request, temporarily switch to a mode where we
            // do blocking `recv`s on the `from_api` receiver in a loop, until we get
            // unpaused. The device emulation is implicitly paused since we do not
            // return to `run_microvm` and hence `event_manager.run()` is not called
            // again: device fds (virtqueue notifications, tap, rate limiters, timers)
            // are not polled until we break out of this loop on `Resume`.
            if request_is_pause {
                // This loop only attempts to process API requests, so things like the
                // metric flush timerfd handling are frozen as well (an explicit `FlushMetrics`
                // request still goes through).
                loop {
                    let req = self.from_api.recv().expect("Error receiving API request.");
                    let req_is_resume = *req == VmmAction::Resume;
                    self._handle_request(*req, event_manager);
                    if req_is_resume {
                        break;
                    }
                }
            }
        }
    }
}
impl MutEventSubscriber for ApiServerAdapter {
    /// Handle a read event (EPOLLIN).
    fn process(&mut self, event: Events, _: &mut EventOps) {
        let source = event.fd();
        let event_set = event.event_set();

        if source == self.api_event_fd.as_raw_fd() && event_set == EventSet::IN {
            let _ = self.api_event_fd.read();

View on GitHub (pinned to 23b09b943f)