netbirdio/netbird · info

xembed: X error (ignored): %s (code=%d, request=%d.%d, resou

Error message

xembed: X error (ignored): %s (code=%d, request=%d.%d, resource=0x%lx)

What it means

Not a failure: a stderr diagnostic printed by the custom Xlib error handler installed for the Linux tray (client/ui/xembed_tray_linux.c). It replaces Xlib's default handler, which calls exit() on any asynchronous X error; returning 0 makes the error a logged no-op so one stray protocol error cannot kill the whole UI process. The message always includes '(ignored)'.

Source

Thrown at client/ui/xembed_tray_linux.c:29

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#define SYSTEM_TRAY_REQUEST_DOCK 0
#define XEMBED_MAPPED            (1 << 0)

/* Xlib's default protocol-error handler calls exit() on any async X error,
   killing the whole UI process. Handlers are process-global (not
   per-Display), so a single install covers our raw tray Display and GDK's.
   Tray work is full of races the X server reports asynchronously — the tray
   manager window dying between xembed_find_tray and xembed_dock (BadWindow
   on XSendEvent), or x11_move_window touching a popup the WM already
   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. */

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. No action needed: the error was already swallowed by design; check whether the tray icon still functions
  2. If the tray icon vanished, restart the tray provider (extension/applet) or relaunch the UI so it re-docks
  3. Keep xembed_install_error_handlers installed; removing it restores Xlib's exit-on-error default and makes these races fatal
Defensive patterns

Strategy: fallback

Prevention

When it happens

Trigger: Asynchronous X errors from tray races the code comments name: the system-tray manager window dying between xembed_find_tray and xembed_dock (BadWindow on XSendEvent), or x11_move_window touching a popup the window manager already destroyed.

Common situations: GNOME/KDE tray extensions or systray daemons restarting while the NetBird UI runs; flaky StatusNotifier/XEmbed support on minimal window managers; the line appears in stderr but the tray and app keep working.

Related errors


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