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