linebender/druid · critical
failed to initialize the keyboard event loop!
Error message
failed to initialize the keyboard event loop!
What it means
The Wayland keyboard backend spawns a background thread running a calloop event loop for key-repeat/input handling. If `calloop::EventLoop::try_new()` fails (event loop infrastructure could not be created, typically an epoll/fd allocation failure), the thread panics with expect and this message, killing keyboard input for the session.
Solutions
- Check the process file-descriptor limit (`ulimit -n`) and raise it; look for fd leaks in the app.
- Verify the sandbox (Flatpak/Snap/seccomp profile) permits epoll syscalls (epoll_create1).
- Run the app outside the sandbox/container to confirm the cause, then adjust the profile.
- Update druid/druid-shell to a version that handles this failure gracefully instead of panicking, or patch the expect into a logged error and degraded keyboard mode.
- Check system memory; epoll allocation can fail under OOM pressure.
Example fix
// before
let mut eventloop = calloop::EventLoop::try_new()
.expect("failed to initialize the keyboard event loop!");
// after
let mut eventloop = match calloop::EventLoop::try_new() {
Ok(el) => el,
Err(e) => { tracing::error!("keyboard event loop init failed: {e}"); return; }
}; Defensive patterns
Strategy: try-catch
Validate before calling
// preflight: ensure epoll and fd headroom before spawning the keyboard thread
let can_epoll = unsafe { libc::epoll_create1(0) } >= 0;
let fd_headroom = {
let mut lim = libc::rlimit { rlim_cur: 0, rlim_max: 0 };
unsafe { libc::getrlimit(libc::RLIMIT_NOFILE, &mut lim) };
lim.rlim_cur > 256
}; Try / catch
// in patched builds, replace expect with graceful degradation:
match calloop::EventLoop::try_new() {
Ok(el) => run_keyboard_loop(el),
Err(e) => log::error!("keyboard loop unavailable: {e}"), // no key repeat
} Prevention
- Raise RLIMIT_NOFILE and fix fd leaks in long-running Wayland sessions.
- Configure Flatpak/Snap/seccomp to allow epoll_create1 and timerfd.
- Keep druid-shell updated for improved wayland backend error handling.
- Monitor startup logs for fd exhaustion symptoms.
When it happens
Trigger: EventLoop::try_new() returning Err due to epoll_create failure — exhausted file descriptors, restrictive seccomp/sandbox blocking epoll, or memory exhaustion — during keyboard backend initialization (Keyboard::default).
Common situations: Running under Flatpak/Snap or container sandboxes with tight fd or syscall limits; hitting RLIMIT_NOFILE in long-running sessions with many fd leaks; embedded/minimal Wayland setups lacking epoll support.
Related errors
- keyboard event processing failed
- failed to initialize the displays event loop!
- unexpected wayland event
- unrecognised key event
- only xkb keymap supported for now
AI-assisted analysis of linebender/druid@0f8b1195e4 (2026-09-10).
Data as JSON: /api/errors/ee3b5f6a11ff27ab.
Report an issue: GitHub.
Appendix: source
Thrown at druid-shell/src/backend/wayland/keyboard.rs:234
impl Default for State {
fn default() -> Self {
let (apptx, apprx) = calloop::channel::channel::<KeyEvent>();
let (tx, rx) = calloop::channel::channel::<(
u32,
wl_keyboard::Event,
calloop::channel::Sender<KeyEvent>,
)>();
let state = Self {
apptx,
apprx: std::cell::RefCell::new(Some(apprx)),
tx,
};
std::thread::spawn(move || {
let mut eventloop: calloop::EventLoop<(calloop::LoopSignal, Keyboard)> =
calloop::EventLoop::try_new()
.expect("failed to initialize the keyboard event loop!");
let signal = eventloop.get_signal();
let handle = eventloop.handle();
let repeat = calloop::timer::Timer::<CachedKeyPress>::new().unwrap();
handle
.insert_source(rx, {
let repeater = repeat.handle();
move |event, _ignored, state| {
let event = match event {
calloop::channel::Event::Closed => {
tracing::info!("keyboard event loop closed shutting down");
state.0.stop();
return;
}
calloop::channel::Event::Msg(keyevent) => keyevent,
};
state.1.consume(event.0, event.1, event.2);
match &state.1.last_key_press {
None => repeater.cancel_all_timeouts(),View on GitHub (pinned to 0f8b1195e4)