fyne-io/fyne · error
eglSwapBuffer failed\n
Error message
eglSwapBuffer failed\n
What it means
Unlike the other x11.c failures, this one fires during the render loop: swapBuffers() calls eglSwapBuffers each frame and exits(1) with 'eglSwapBuffer failed' (the message misspells eglSwapBuffers) when the swap returns EGL_FALSE. That means the surface is no longer swap-able: the window/surface was destroyed, the EGL context was lost (GPU reset, suspend/resume), or the display connection dropped mid-run.
Source
Thrown at internal/driver/mobile/app/x11.c:172
onTouchMove((float)ev.xmotion.x, (float)ev.xmotion.y);
break;
case ConfigureNotify:
onResize(ev.xconfigure.width, ev.xconfigure.height);
break;
case ClientMessage:
if (wm_delete_window != None && (Atom)ev.xclient.data.l[0] == wm_delete_window) {
onStop();
return;
}
break;
}
}
}
void
swapBuffers(void) {
if (eglSwapBuffers(e_dpy, e_surf) == EGL_FALSE) {
fprintf(stderr, "eglSwapBuffer failed\n");
exit(1);
}
}
View on GitHub (pinned to 8860ee95c3)
Solutions
- Restart the application after GPU/driver resets or suspend/resume cycles; the process exits immediately by design
- Keep the display connection and window alive for the whole render loop; do not destroy the window from another goroutine/thread mid-swap
- Update Mesa/GPU drivers to reduce spurious context loss
- If you build the driver, replace exit(1) with an eglMakeCurrent retry or surface recreation on EGL_CONTEXT_LOST
Example fix
// before (x11.c): any failed swap kills the process
void
swapBuffers(void) {
if (eglSwapBuffers(e_dpy, e_surf) == EGL_FALSE) {
fprintf(stderr, "eglSwapBuffer failed\n");
exit(1);
}
}
// after: attempt recovery once before giving up
void
swapBuffers(void) {
if (eglSwapBuffers(e_dpy, e_surf) == EGL_FALSE) {
if (eglGetError() == EGL_CONTEXT_LOST && eglMakeCurrent(e_dpy, e_surf, e_surf, e_ctx))
return;
fprintf(stderr, "eglSwapBuffer failed\n");
exit(1);
}
} Defensive patterns
Strategy: validation
Validate before calling
func swapPreflight(w fyne.Window) error {
if w == nil || w.Canvas() == nil {
return fmt.Errorf("window/canvas destroyed; cannot swap buffers")
}
return nil
} Prevention
- Destroy windows only through the driver's normal lifecycle, never from arbitrary goroutines mid-frame
- Expect and handle app exit after suspend/resume or GPU resets; restart the process as recovery
- If vendoring this code, patch swapBuffers to retry eglMakeCurrent on EGL_CONTEXT_LOST instead of exiting
When it happens
Trigger: Calling swapBuffers() after the window has been closed/destroyed, after a driver/GPU reset invalidates the context, or while the X display connection is being torn down (session ending, SSH dropping).
Common situations: Laptop suspend/resume under the app; closing the window while a frame swap is in flight; driver crashes/recovery (TDR); long-running kiosk apps across display restarts.
Related errors
- eglChooseConfig failed\n
- eglGetConfigAttrib failed\n
- XGetVisualInfo failed\n
- eglCreateWindowSurface failed\n
- eglGetDisplay failed\n
AI-assisted analysis of fyne-io/fyne@8860ee95c3 (2026-08-15).
Data as JSON: /api/errors/d8f3e1c7c696c1e6.
Report an issue: GitHub.