Still capture works, the saved JPEG looks clean, and the moment you ask for a live preview the run dies with libEGL warnings about DRI3 and DRI2. That pins the fault to the desktop session's rendering stack, not to the camera. Here you will read the log in one pass, pick the cause from the five that produce these exact warnings, and apply one of three fixes: a system update, a DRI3-capable display path, or a Qt preview window that removes the GL dependency entirely.
Read the log first: the camera side is already proven
Every line before 'Made X/EGL preview window' is acquisition. The failing log on a Raspberry Pi 5 shows libcamera v0.5.1+100-e53bdf1f and libpisp v1.2.1 loading, then the sensor registering: 'Registered camera /base/axi/pcie@1000120000/rp1/i2c@80000/imx477@1a to CFE device /dev/media1 and ISP device /dev/media2 using PiSP variant BCM2712_D0'. Stream setup follows, with a 2028x1520-YUV420 preview stream plus the raw stream, and mode selection completes. Only then is the window created:
Made X/EGL preview window
libEGL warning: DRI3: Screen seems not DRI3 capable
libEGL warning: DRI2: failed to authenticate
MESA: error: ZINK: failed to choose pdev
libEGL warning: egl: failed to create dri2 screen
No camera-side line carries an error. The sensor was detected, the ISP was configured, and frames were being produced before the first EGL call ran. That is the decision rule for this whole fault class: clean acquisition lines plus a dead window creation means a rendering problem. The same capture-versus-render split applies to every stack, not just libcamera — camera window opens but no video: isolate capture from rendering walks the isolation step by step.
What DRI3 and DRI2 mean in the log
EGL is the library that creates a GPU-backed surface for the preview window. Mesa first asks the X server for a DRI3 device, the current acceleration handshake; the server answers that the screen is not DRI3 capable. It retries over DRI2, the older handshake, and the authentication step fails. The final fallback is Zink, Mesa's software OpenGL path, which finds no device to run on ('failed to choose pdev'). EGL now has no usable screen, so the preview context creation fails and the tool aborts.
Three libEGL warnings and one MESA error, in that order, mean the whole chain was walked and every rung refused. Two situations produce it most often on a Pi: a display path that cannot expose DRI3, which in practice means keeping the desktop on the HDMI output, and a session that is not really local, such as VNC or forwarded X, where EGL has nothing to authenticate against. A Lite image without the full desktop stack leaves the preview with no windowing system at all.
Likely causes, most probable first
- The OS build predates the DRI3 fix. Bookworm builds without it warn exactly this way on healthy hardware. Test: update the system (Fix 1) and rerun after a reboot.
- The display path cannot do DRI3. Adapter chains and non-HDMI display paths leave the server reporting a screen that is not DRI3 capable. Test: drive the desktop from the Pi's own HDMI output, at the bench (Fix 2).
- The session is remote. VNC and X forwarding give EGL nothing to authenticate. Test: run the same command on the local desktop; if you must stay remote, use Fix 3.
- The user cannot open the render nodes. A session without access to /dev/dri fails identically. Test: list /dev/dri and confirm your user sits in the render and video groups; add them and log in again.
- There is no desktop stack. A Lite image has no windowing system for the EGL preview to attach to. Test: run the full desktop image, or drop the preview with Fix 3.
Worked example: Raspberry Pi 5 on Bookworm with an IMX477 camera
Inputs, with their sources:
- Board and OS: Raspberry Pi 5, Raspberry Pi OS 12 (Bookworm), booted to the local X11 desktop (run log).
- Camera: a CSI module with an IMX477 sensor, registered to CFE device /dev/media1 and ISP device /dev/media2 on PiSP variant BCM2712_D0 (run log).
- Streams: 2028x1520-YUV420 preview plus the raw stream, set up before the window call (run log).
- Errors: three libEGL warnings and one MESA error, all after the window line (run log).
- Fix availability: the DRI3 preview fix ships through the normal package repositories (Raspberry Pi OS update channel).
Rule in words: split the log at the window-creation line and count errors on each side. A healthy run leaves zero errors in the acquisition half; rendering failures all land in the second half.
Arithmetic: the acquisition half configured a preview stream of 2028 x 1520 = 3,084,480 pixels. YUV420 costs 1.5 bytes per pixel, so one preview frame is 3,084,480 x 1.5 = 4,626,720 bytes, about 4.6 MB — memory the ISP was already filling before any EGL call ran. The error half holds 4 lines, all display-side: 3 libEGL warnings + 1 MESA error = 4, and camera-side errors = 0.
Result: the imaging chain proved itself on a multi-megapixel stream, and the only failures sit between EGL and the X server.
Decision: if the saved stills are good and every error line sits after the window line, apply the display fixes in order — update first, HDMI session second, Qt preview as the permanent setting. The threshold is strict: a single camera-side error (a sensor that fails to register, a mode that fails to set) and this is a different fault — fix acquisition before touching the desktop.
Fix 1: update Raspberry Pi OS and reboot
The DRI3 preview fix is in the public repositories, so a normal system update carries it:
sudo apt update
sudo apt dist-upgrade
Reboot before retesting. EGL talks to the drivers the running session loaded at login, so an upgrade without a restart keeps the old session and the same warnings. Rerun the capture tool with the preview enabled; on a Bookworm install whose only fault is the missing fix, the DRI3 warning is gone here and the window opens.
Fix 2: give the session a DRI3-capable display
Run the tool at the bench, on the desktop the Pi itself drives, with the monitor on the HDMI output. The session must be the local one — a VNC window showing the same wallpaper is still a remote session to EGL — and the display path should be the HDMI port rather than an adapter chain. If you installed the Lite image, install the full desktop: without a windowing system the EGL preview has nothing to attach to, which shows up as a 'Preview window unavailable' failure on a perfectly healthy camera.
Fix 3: switch the preview window to Qt
The rpicam tools and the Python libcamera bindings let you choose the preview window type. The EGL default needs a DRI-capable X session; the Qt preview renders through the toolkit instead, so it works where DRI3 and DRI2 are refused. Select the Qt preview in the tool's preview setting — the exact flag or argument spelling differs slightly between releases, so take it from the tool's own help output. For unattended runs, disable the preview entirely and read the saved frames; that is the setting production should keep.
This is also the design answer: a station does not need a GL window, it needs frames. If you are wiring capture into a larger application, camera live preview in GUI applications covers the same choice from the application side.
Remote sessions: why the window cannot follow you
VNC relays drawn pixels and X forwarding passes protocol messages; neither hands EGL a device it can authenticate, so the preview fails remotely even when it works at the bench. Run remote sessions with the Qt preview or no preview, and treat a works-locally-fails-remotely result as confirmation rather than a new fault. For a machine that must show a live image with no desktop at all, put the render where the display is — the role remote client no video? Put the display window on the front panel works through, and the one industrial panel PCs are built for.
Prevention: keep capture independent of preview
The pattern that makes this failure class harmless: acquisition runs as its own producer with its own buffers, and the preview is a consumer that can die without stopping it. Concretely, start unattended runs with the preview disabled, log to files or a stream, and bring a window up only while you are tuning. The same layering lets you swap cameras or move hosts without touching display code — the machine vision camera on Raspberry Pi: build the capture stack guide lays those layers out, and GPU accelerated vision streaming: trace the video pipeline shows where rendering sits in a streaming path.
When the prototype becomes a machine
A CSI module on a Pi is the right prototype tool, and the desktop fixes above keep it running. When the project turns into a station, two catalog paths take the desktop out of the capture equation. GigE and USB3 board-level cameras expose a machine-vision capture path that never routes through the desktop's GL, and the same holds for C-mount area scan cameras; choosing the interface is its own decision, covered in UVC camera not detected by software: choose the right capture path. For the box that runs the station, vision controllers combine camera LAN ports with built-in light-controller channels, and the system configurator steps through camera, lens and light together.
These board-level modules fit this build:
- Sensor format
- 1/1.8"
- Lens mount
- CS-mount
- Sensor format
- 1/1.8"
- Interface
- USB3
And a controller sized for a small multi-camera station:
- LAN ports
- 3-4 LAN ports
- USB 3 ports
- 2 USB 3 ports
- Light outputs
- 4 built-in channels
- Memory
- 8 GB
The LS-BCM-0020 is a 6.3 MP GigE module on an IMX178 sensor with a CS-mount, rated 18 fps; the MV-CB060-10UM-B is the 6 MP USB3 variant as a bare board for tight housings. The MV-VC2140-128G40-1T brings an N97 (Intel N-series) controller with 3-4 LAN ports, 2 USB 3 ports and 4 built-in light channels.
Checklist before you reflash anything
- Save one still image and open it — a clean JPEG proves sensor, cable and ISP.
- Read the full crash log and find the camera registration line — its presence localizes the fault to rendering.
- Count the error lines after 'Made X/EGL preview window' — three libEGL warnings plus one MESA error means the whole fallback chain was walked.
- Run the system update and reboot, then retest — the DRI3 fix arrives this way.
- Move the session to the local HDMI desktop and retest — this removes the display-path and remote-session causes.
- Rerun with the Qt preview — this is the setting that survives every later desktop change.
Questions
Why does still image capture work but the live preview crash?
The capture path writes frames straight to a file and never creates a GPU drawing surface; the preview path must first build an EGL window inside the X session. When that session has no DRI3 or DRI2 device, window creation dies while capture keeps working. Whenever the saved stills are clean, treat the crash as a display-stack fault and fix the session, not the camera.
Can I get a live preview over VNC or SSH?
VNC relays already-drawn pixels and X forwarding only passes protocol messages; neither hands EGL a device it can authenticate against, so the EGL preview fails remotely even when it works at the bench. Use the Qt preview window for remote runs, or capture with no preview window and view the saved files afterwards.
What does 'ZINK: failed to choose pdev' mean?
Zink is Mesa's software OpenGL path, the last rung after hardware DRI3 and DRI2 are refused. 'failed to choose pdev' means that path found no device to run on either, so EGL could not create the preview context at all. The message names rendering only; the camera lines above it in the log were clean.
Does this error hurt the camera or the Raspberry Pi?
No. Acquisition completed before the preview window was attempted: the sensor registered, the ISP was configured and frames were delivered. The crash happens in the display client after the imaging chain did its job, so repeated crashes cost debugging time, not hardware. Leave imaging settings untouched while you repair the desktop session.
Which fix should I try first on a fresh Bookworm install?
Run the system update first: sudo apt update, then sudo apt dist-upgrade, and reboot so the new session picks up the fixed drivers. That clears it on most boards whose only fault is the missing fix. If the warnings return after the reboot, move the desktop to the HDMI output, then make the Qt preview the permanent setting.


