fyne-io/fyne · critical

XOpenDisplay failed\n

Error message

XOpenDisplay failed\n

What it means

The very first step of createWindow() in x11.c: XOpenDisplay(NULL) opens a connection to the X server named by $DISPLAY. Returning NULL means no display could be opened at all, and the process prints 'XOpenDisplay failed' and exits(1). Nothing graphical can proceed.

Source

Thrown at internal/driver/mobile/app/x11.c:101

	*surf = eglCreateWindowSurface(e_dpy, config, win, NULL);
	if (!*surf) {
		fprintf(stderr, "eglCreateWindowSurface failed\n");
		exit(1);
	}
	return win;
}

Display *x_dpy;
EGLDisplay e_dpy;
EGLContext e_ctx;
EGLSurface e_surf;
Window win;

void
createWindow(void) {
	x_dpy = XOpenDisplay(NULL);
	if (!x_dpy) {
		fprintf(stderr, "XOpenDisplay failed\n");
		exit(1);
	}
	e_dpy = eglGetDisplay(x_dpy);
	if (!e_dpy) {
		fprintf(stderr, "eglGetDisplay failed\n");
		exit(1);
	}
	EGLint e_major, e_minor;
	if (!eglInitialize(e_dpy, &e_major, &e_minor)) {
		fprintf(stderr, "eglInitialize failed\n");
		exit(1);
	}
	eglBindAPI(EGL_OPENGL_ES_API);
	win = new_window(x_dpy, e_dpy, 500, 1000, &e_ctx, &e_surf);

	wm_delete_window = XInternAtom(x_dpy, "WM_DELETE_WINDOW", True);
	if (wm_delete_window != None) {
		XSetWMProtocols(x_dpy, win, &wm_delete_window, 1);

View on GitHub (pinned to 8860ee95c3)

Solutions

  1. Start an X server and point DISPLAY at it: export DISPLAY=:0
  2. For headless runs use Xvfb: xvfb-run -a -s '-screen 0 1024x768x24' ./yourapp
  3. For SSH access use ssh -X (X forwarding) so DISPLAY is set
  4. If you need offscreen rendering without any X server, use a headless driver/tooling instead of the X11 mobile path

Example fix

# before: headless shell, no DISPLAY
./yourapp  # XOpenDisplay failed

# after: virtual X server with GLX
xvfb-run -a -s '-screen 0 1024x768x24 +extension GLX' ./yourapp
Defensive patterns

Strategy: validation

Validate before calling

func displayPreflight() error {
	if os.Getenv("DISPLAY") == "" {
		return fmt.Errorf("DISPLAY is not set; export DISPLAY=:0 or use xvfb-run")
	}
	if err := exec.Command("xdpyinfo").Run(); err != nil {
		return fmt.Errorf("X server at DISPLAY=%s unreachable: %w", os.Getenv("DISPLAY"), err)
	}
	return nil
}

Prevention

When it happens

Trigger: DISPLAY unset or pointing at a dead server; running the Fyne mobile/X11 driver binary in a headless container, SSH session, or service context with no X server.

Common situations: CI pipelines and Docker containers without an X server; cron/systemd services; SSH without X forwarding; typos in DISPLAY (e.g. :1 when the server is :0); Xvfb not started yet.

Related errors


AI-assisted analysis of fyne-io/fyne@8860ee95c3 (2026-08-15). Data as JSON: /api/errors/91b6a1e0e745ea67. Report an issue: GitHub.