netbirdio/netbird · error

xembed: X I/O error (connection lost)

Error message

xembed: X I/O error (connection lost)

What it means

stderr line from xembed_x_io_error_handler: the process-global I/O error handler fires when the X connection itself is lost (server gone, socket closed). Xlib treats an I/O error as fatal and exits the process even if the handler returns, so this handler can only log a clearer line than Xlib's default before the unavoidable exit.

Source

Thrown at client/ui/xembed_tray_linux.c:42

   destroyed — and the default handler would take us down for any of them.
   Returning 0 here makes the error a logged no-op instead. */
static int xembed_x_error_handler(Display *dpy, XErrorEvent *ev) {
    char buf[256];
    XGetErrorText(dpy, ev->error_code, buf, sizeof(buf));
    fprintf(stderr,
            "xembed: X error (ignored): %s (code=%d, request=%d.%d, resource=0x%lx)\n",
            buf, ev->error_code, ev->request_code, ev->minor_code,
            ev->resourceid);
    return 0;
}

/* The I/O error handler fires when the X connection itself drops (server
   gone, socket closed). Xlib treats this as fatal and exits even if we
   return, so this can't keep the process alive — it only logs a clearer
   line than Xlib's terse default before the unavoidable exit. */
static int xembed_x_io_error_handler(Display *dpy) {
    (void)dpy;
    fprintf(stderr, "xembed: X I/O error (connection lost)\n");
    return 0;
}

/* Install the process-global handlers. Idempotent and cheap, so callers may
   invoke it after every XOpenDisplay without tracking prior installs. */
void xembed_install_error_handlers(void) {
    XSetErrorHandler(xembed_x_error_handler);
    XSetIOErrorHandler(xembed_x_io_error_handler);
}

Window xembed_find_tray(Display *dpy, int screen) {
    char atom_name[64];
    snprintf(atom_name, sizeof(atom_name), "_NET_SYSTEM_TRAY_S%d", screen);
    Atom sel = XInternAtom(dpy, atom_name, False);
    return XGetSelectionOwner(dpy, sel);
}

int xembed_get_icon_size(Display *dpy, Window tray_mgr) {

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Nothing prevents the exit from inside the handler by design; run the UI under a supervisor (systemd --user, desktop session) that restarts it
  2. Persist any UI state outside the X event loop so an X-disconnect exit loses nothing
  3. If this happens mid-session on Wayland, check whether XWayland crashed (journalctl) rather than suspecting the NetBird UI
Defensive patterns

Strategy: fallback

Prevention

When it happens

Trigger: Logging out or shutting down/restarting the X server while the tray is connected; XWayland terminating when the Wayland session ends; a dropped 'ssh -X' forwarded session; an X server crash.

Common situations: Session teardown on Linux desktops; the UI running under a remote or virtual X display that disappears; Wayland sessions where XWayland stops unexpectedly.

Related errors


AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16). Data as JSON: /api/errors/1892410a90dd8208. Report an issue: GitHub.